Junit单元测试
黑盒测试:
白盒测试:
需要写代码的,看程序执行的具体过程—-如:Junit单元测试
不能传参
@Before @After
package com.igeek_01;
/**
* @author Lynn
* @create 2020-12-18-9:29
*/
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* junit测试适用于代码的测试,是单元测试用于替代main方法
*/
public class JunitTest01 {
@Test
public void test01(){
System.out.println("运行1通过");
}
@Test
public void test02(){
System.out.println("运行2通过");
}
/**
* @Before
* @After
*/
@Before
public void Before(){
System.out.println("在@Test方法之前运行");
}
@After
public void after(){
System.out.println("在@Test方法之后运行");
}
}
运行结果:
在@Test方法之前运行
运行1通过
在@Test方法之后运行
在@Test方法之前运行
运行2通过
在@Test方法之后运行
package com.igeek_01;
/**
* @author Lynn
* @create 2020-12-18-10:00
*/
/**
* Junit测试类也是一个普通的类,也可以实例化
*/
public class JunitTest02 {
public static void main(String[] args) {
//实例化这个类
JunitTest01 test01=new JunitTest01();
test01.test01();
test01.after();
test01.Before();
}
}
运行结果:
运行1通过
在@Test方法之后运行
在@Test方法之前运行
反射机制—reflect
定义:
** ****是在运行状态中,在任意一个类中,都能够知道他的所有的属性和方法;对于任意一个对象,都能够调用他的所有的属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称之为java语言的反射机制。**<br />** 每一个类,都会被appclassloader加载到方法区,生成Class类型的对象**<br />
获取类对象的方法
1.使用类:Class clazz=Student.class;
2.使用全类名(包名.类名)—比较常用—安全
Class clazz=Class.forName(“com.igeek_02.Student”);
3.使用对象:
Student s=new Student();
Class clazz=s.getClass();
package com.igeek_02;
/**
* @author Lynn
* @create 2020-12-18-10:11
*/
/**
* 实体类
* 用于测试反射
*/
public class Student {
//字段--属性
public int id;
private String name;
//构造
public Student() {
super();
}
public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}
//方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
//私有方法--用于测试
private void setName(String name) {
this.name = name;
}
//静态方法
public static int getCount(int c){
return c*10;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
package com.igeek_02;
/**
* @author Lynn
* @create 2020-12-18-10:04
*/
import org.junit.Test;
/**
* java反射机制
*
* 目前讲反射是讲解反射的使用
*/
public class ReflectDemo {
//单元测试
@Test
public void test1(){
//已知明确的类型,获取Class对象
Class clazz=Student.class;
System.out.println(clazz);//class com.igeek_02.Student
}
@Test
public void test2(){
//已知对象,获取Class对象
Student s=new Student();
Class clazz=s.getClass();//getClass()是顶级父类Object中的方法
System.out.println(clazz);//class com.igeek_02.Student
}
@Test
public void test3() throws ClassNotFoundException {
//完全限定名(包名.类名),获取Class对象--比较常用--安全
String className="com.igeek_02.Student";
//forName()返回这个地址值所对应的类
Class clazz=Class.forName(className);
System.out.println(clazz);//class com.igeek_02.Student
}
//测试结果:通过不同的反射获取的对象是同一个!!
@Test
public void test4() throws ClassNotFoundException {
//第一种
Class clazz1=Student.class;
//第二种
Student s=new Student();
Class clazz2=s.getClass();
//第三种
String className="com.igeek_02.Student";
Class clazz3=Class.forName(className);
//比较
System.out.println(clazz1==clazz2);
System.out.println(clazz1==clazz3);
System.out.println(clazz3==clazz2);
}
}
package com.igeek_02;
/**
* @author Lynn
* @create 2020-12-18-10:31
*/
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 通过java的反射机制构建对象的测试
*/
public class ReflectDemo2 {
@Test
public void test01() throws IllegalAccessException, InstantiationException {
//类中有无参构造
Class clazz=Student.class;
Object obj=clazz.newInstance();//默认调用的是无参的--创建实例
System.out.println(clazz);//class com.igeek_02.Student
System.out.println(obj);//Student{id=0, name='null'}--
// 当前的object进行了向下转型给了反射获取到的类Student
}
@Test
public void test02() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取Class类中的构造函数对象
Class clazz=Student.class;
//获取到有参构造函数
Constructor con= clazz.getConstructor(int.class, String.class);
Object obj = con.newInstance(20, "Tom");
System.out.println(obj);//Student{id=20, name='Tom'}
}
//演示普通的方式实例化对象做不到的事情
@Test
public void test03(){
Student s=new Student();
s.setId(1);
// s.setName();//不能进行name赋值,因为方法是私有的
System.out.println(s);//Student{id=1, name='null'}
}
}
package com.igeek_02;
/**
* @author Lynn
* @create 2020-12-18-11:14
*/
import com.sun.deploy.xml.XMLable;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 反射处理静态方法
*/
public class ReflectDemo3 {
@Test
public void test01(){
//静态方法的调用--普通
int count=Student.getCount(10);
System.out.println(count);//100
}
@Test
public void test02() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//静态方法的调用--利用反射机制处理
//1.创建Class
String className="com.igeek_02.Student";
Class clazz=Class.forName(className);
//2.调用静态方法
Method hetCount = clazz.getMethod("getCount", int.class);
//3.根据类型传参--invoke方法表示映射,这里因为不需要实例,所以可以传参null
Object obj=hetCount.invoke(null,2);
System.out.println(obj);//20
}
}
获取字段—Field—-获取值和修改值
package com.igeek.ziduan;
import org.junit.Test;
import java.lang.reflect.Field;
/**
* @author Lynn
* @create 2020-12-21-9:31
*/
public class FieldTest01 {
//利用反射机制处理公共字段
@Test
public void test2() throws Exception{
//获取类
Class clazz=Class.forName("com.igeek.ziduan.Student");
//创建实例对象
Object o = clazz.newInstance();
//处理字段
Field id = clazz.getField("id");
id.set(o,30);
System.out.println(o);
//通过key获取值
Object o1 = id.get(o);
System.out.println(o1);
}
//利用反射机制处理私有字段
@Test
public void test3() throws Exception{
//获取类
Class clazz=Class.forName("com.igeek.ziduan.Student");
//创建实例对象
Object o = clazz.newInstance();
//处理字段
Field name = clazz.getDeclaredField("name");
System.out.println(name);//private java.lang.String com.igeek.ziduan.Student.name
//打破私有权限
name.setAccessible(true);
name.set(o,"Lynn");
System.out.println(o);//Student{id=0, name='Lynn'}
//通过key获取值
Object o1 = name.get(o);
System.out.println(o1);//Lynn
}
}
获取方法—-invoke—用来调用
构造方法—-核心是用来构造对象的—new对象
讲解Properties使用
映射—在properties中使用Map—通过键找到值
package com.igeek.properties;
import org.junit.Test;
import java.io.*;
import java.util.Properties;
/**
* @author Lynn
* @create 2020-12-21-9:47
*/
public class PropertiesDemo {
//第一种方式:添加内容,使用Map中的方法--put
@Test
public void test1() throws IOException {
//保存properties的数据到流中--void store(OutputStream out,String content)
Properties prop=new Properties();
prop.put("id","100");
prop.put("name","Lynn");
prop.store(new FileOutputStream("t.txt"),"要写入的内容");//内容的Unicode
}
//读取流--void load(InputStream in)
@Test
public void test2() throws IOException {
Properties prop=new Properties();
//读取
prop.load(new FileInputStream("t.txt"));
System.out.println(prop);//{name=Lynn, id=100}
//
String id = prop.getProperty("id");
System.out.println(id);
String name = prop.getProperty("name");
System.out.println(name);
}
//第二种方式:使用properties方法设置数据--setProperty
@Test
public void test3() throws IOException {
Properties prop=new Properties();
prop.setProperty("id","20");
prop.setProperty("name","Cheery");
prop.store(new FileOutputStream("t2.txt"),"过");
// System.out.println(prop);//{name=Cheery, id=20}
//通过key获取值
String id = prop.getProperty("id");
String name = prop.getProperty("name");
/*String id = prop.getProperty("id1");
System.out.println(id);*///如果key炸不到则返回null
// System.out.println(name);
}
//读取
@Test
public void test4() throws IOException {
Properties prop=new Properties();
prop.load(new FileInputStream("t2.txt"));
System.out.println(prop.get("id"));
System.out.println(prop.get("name"));
}
}
配置文件—利用properties类实现不修改源码的基础上处理数据
注意:从**properties**中获取的都是字符串类型
package com.igeek.config;
/**
* @author Lynn
* @create 2020-12-21-10:32
*/
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
/**
* 利用properties类实现不修改源码的基础上处理数据
*/
public class ConfigTest {
@Test
public void test1(){
//测试学生和老师的对象
Student s=new Student(54,"Lynn");
System.out.println(s);
Teacher t=new Teacher(54,"Lynn");
System.out.println(t);
}
/**
*从配置文件className中读取要获取哪一个类
* 好处:获取哪个类直接修改配置文件,不需要修改源代码
* 1.首先要获取配置文件
*/
@Test
public void test2() throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//从className中读取类名
Properties prop=new Properties();
//加载配置文件并且读取
prop.load(new FileReader("className.properties"));
//根据key获取value
String className= prop.getProperty("className");
System.out.println(className);//com.igeek.config.Teacher
//创建类的实例--反射
Class clazz=Class.forName(className);
//找到该类的构造器--有参
Constructor constructor = clazz.getConstructor(int.class, String.class);
//利用构造函数处理数据
Object o = constructor.newInstance(54, "Lynn");
System.out.println(o);
}
/**
* 从配置文件data.properties中读取数据并且填入实例
*
*/
@Test
public void test3() throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//从className中读取类名
Properties prop=new Properties();
//加载配置文件并且读取
prop.load(new FileReader("className.properties"));
//根据key找到value
String className = prop.getProperty("className");
//创建实例
Class clazz=Class.forName(className);
//构造函数中进行处理
//1.从data配置文件中获取数据
Properties prop_Data=new Properties();
prop_Data.load(new FileReader("data.properties"));
String v_id = prop_Data.getProperty("id");
String v_name = prop_Data.getProperty("name");
System.out.println(v_id+v_name);
//将数据写入对象
Constructor constructor = clazz.getConstructor(int.class, String.class);
//从properties中获取的都是字符串类型,所以要强制转换为int类型--parseInt
Object o = constructor.newInstance(Integer.parseInt(v_id),v_name);
System.out.println(o);
}
}
BeanUtils工具类
package com.igeek.user;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
/**
* @author Lynn
* @create 2020-12-21-11:27
*/
public class BeanUtilsDemo {
//常规的--调用get/set方法
@Test
public void test1(){
User use=new User();
use.setUid("u001");
use.setUsername("Lynn");
System.out.println(use);//User{uid='u001', username='Lynn', password='null', hobbies=null, age=0}
}
//使用BeanUtils工具进行封装--底层调用的还是get/set方法
@Test
public void test2() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
User use=new User();
//
BeanUtils.setProperty(use,"uid","u002");
//封装配置文件
BeanUtils.setProperty(use,"username","Cheery");
BeanUtils.setProperty(use,"password","123");
System.out.println(use);//User{uid='u002', username='Cheery', password='123', hobbies=null, age=0}
//获取值
System.out.println(BeanUtils.getProperty(use, "username"));//Cheery
//如果找不到会报错
/*System.out.println(BeanUtils.getProperty(use, "username1"));
//java.lang.NoSuchMethodException: Unknown property 'username1' on class 'class com.igeek.user.User'*/
}
}
BeanUtils**类的populate(Object bean, Map
将Map数据封装到指定Javabean中,一般用于将表单的所有数据封装到javabean。**
package com.igeek.user;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* @author Lynn
* @create 2020-12-21-11:27
*/
/**
* BeanUtils的方法讲解
*/
public class BeanUtilsDemo1 {
//使用populated方法进行填充数据方法1
@Test
public void test1() throws InvocationTargetException, IllegalAccessException {
//1.模拟数据,创建map,填充所需要的数据
Map<String,String[]> map=new HashMap<>();
map.put("uid",new String[]{"u007"});
map.put("username",new String[]{"王嘉尔"});
map.put("password",new String[]{"123"});
//2.使用populate方法进行填充
User user=new User();
BeanUtils.populate(user,map);
System.out.println(user);
}
//使用BeanUtils工具进行封装--底层调用的还是get/set方法
@Test
public void test2() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Map<String,String[]> map=new HashMap<>();
map.put("uid",new String[]{"u008"});
//底层:就是调用了setUsername方法
map.put("username",new String[]{"郭靖","黄蓉"});
map.put("password",new String[]{"123"});
map.put("hobbies",new String[]{"降龙十八掌","碧海潮生曲","打狗十八式"});
map.put("age",new String[]{"45"});
//2.使用populate方法进行填充
/**
* 可以指定属性,统一进行填充,需要的类型是数组[]
* 如果属性不是数组,将使用map.value表示数组中的第一个数据--
* 黄蓉不是第一个数据,所以不见了
* BeanUtils支持的类型:基本类型和基本类型对应的包装类,
* 自动将字符串转换为基本类型--自己做的
*/
User user=new User();
BeanUtils.populate(user,map);
System.out.println(user);//User{uid='u008', username='郭靖', password='123', hobbies=[降龙十八掌, 碧海潮生曲, 打狗十八式], age=45}
}
}
自定义BeanUtils工具类
package com.igeek.user;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* @author Lynn
* @create 2020-12-21-11:27
*/
/**
* 自定义BeanUtils工具类
*/
public class BeanUtilsDemo2 {
//自动填充
public static void populate(Object bean,Map<String,String[]> properties){
try {
BeanUtils.populate(bean,properties);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//自动填充的方法,并且返回bean对象
public static Object populate(Class beanClass,Map<String,String[]> properties){
try {
Object bean = beanClass.newInstance();
//
BeanUtils.populate(bean,properties);
return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.igeek.user;
/**
* @author Lynn
* @create 2020-12-21-15:07
*/
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* 测试自定义的方法--populate
*/
public class MyBeanUtilsTest {
//测试没有返回值的方法
@Test
public void test1(){
Map<String,String[]> map=new HashMap<>();
map.put("uid",new String[]{"u007"});
map.put("username",new String[]{"王嘉尔"});
map.put("password",new String[]{"123"});
//2.使用populate方法进行填充
User user=new User();
BeanUtilsDemo2.populate(user,map);
System.out.println(user);
}
//测试有返回值的方法
@Test
public void test2(){
Map<String,String[]> map=new HashMap<>();
map.put("uid",new String[]{"u007"});
map.put("username",new String[]{"王嘉尔"});
map.put("password",new String[]{"123"});
//2.使用populate方法进行统一的填充--向下转型--因为自己封装的方法返回的是Object类型,
//所以如果要获取,指定的类型就必须向下转型
User user = (User) BeanUtilsDemo2.populate(User.class, map);//向下转型
System.out.println(user);
}
}
带泛型的自定义工具类
package com.igeek.MyBeanUtils;
/**
* @author Lynn
* @create 2020-12-21-15:53
*/
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
/**
* MyBeanUtils泛型使用
*/
public class MyBeanUtils {
/**
*
* @param beanClass
* @param properties
* @return
*
* Class<T>此时这个T就是一个变量,在运行的时候,接收具体的类型。例如:User
* 变量必须先定义再使用
* 泛型变量的定义方式,修饰符<变量名> 返回值
*/
public static <T> T populate(Class<T> beanClass, Map<String,String[]> properties){
try {
//1.使用反射机制实例化
T bean=beanClass.newInstance();
//2.填充数据
BeanUtils.populate(bean,properties);
//返回数据
return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.igeek.MyBeanUtils;
/**
* @author Lynn
* @create 2020-12-21-16:00
*/
import com.igeek.user.User;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* 测试自定义泛型的BeanUtils
*/
public class MyBeanUtilsTest {
@Test
public void test1(){
Map<String,String[]> map=new HashMap<>();
map.put("uid",new String[]{"u007"});
map.put("username",new String[]{"王嘉尔","王一博"});
map.put("password",new String[]{"123"});
//数据填充--用到了泛型
User user = MyBeanUtils.populate(User.class, map);
System.out.println(user);
}
}
xml文件
DOM4j工具
package com.igeek.Dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
/**
* @author Lynn
* @create 2020-12-23-10:34
*/
public class DOM4jDemo {
//测试DOM4j解析
@Test
public void testParse() throws DocumentException {
//1.获取核心类--import org.dom4j.io.SAXReader;
SAXReader saxReader=new SAXReader();
//2.获取整个xml文档--import org.dom4j.Document;
Document document= saxReader.read("beans.xml");
//3.获取所有beans--import org.dom4j.DocumentException;
Element rootElement= document.getRootElement();
//4.获取所有的子节点
List<Element> allBeanElement = rootElement.elements("bean");
//遍历集合
for (Element beanEle:allBeanElement){
//根据自己设定的属性进行解析--bean
String id=beanEle.attributeValue("id");
String className=beanEle.attributeValue("className");
System.out.println("bean的属性:"+id+","+className);
//获取子元素的property
List<Element> property = beanEle.elements("property");
for (Element propEle:property){
String name=propEle.attributeValue("name");
String value=propEle.attributeValue("value");
System.out.println("property的属性:"+name+","+value);
}
}
// System.out.println();//换行
}
}
综合案例1—工厂模式
package com.igeek.Dom4j_02;
/**
* @author Lynn
* @create 2020-12-23-11:23
*/
import java.util.Properties;
/**
* javaBean的配置对象
*
* BeanConfig文件用于将对应的xml的配置项,解析封装到对象中
* 属性:id,className,property
*
* 当前这个实体类的实例化beans.xml文件,相当于是一个属性配置的中转站
* 后面进行的操作都是通过中转站处理的
*/
public class BeanConfig {
private String id;
private String className;
//用于解析当前的这个bean中的所有的属性,所以直接创建一个properties的对象
private Properties props=new Properties();
public BeanConfig(){
}
public BeanConfig(String id, String className, Properties props) {
this.id = id;
this.className = className;
this.props = props;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Properties getProps() {
return props;
}
public void setProps(Properties props) {
this.props = props;
}
@Override
public String toString() {
return "BeanConfig{" +
"id='" + id + '\'' +
", className='" + className + '\'' +
", props=" + props +
'}';
}
}
package com.igeek.Dom4j_02;
/**
* @author Lynn
* @create 2020-12-23-14:00
*/
import org.apache.commons.beanutils.BeanUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 设计模式:23种,常用的有:
* 单例模式,工厂模式,代理模式,模板模式...
*
* 工厂模式:
*/
public class BeanFactory {
//1.提供map存放beans.xml中的配置文件内容,使用map,建议使用静态处理--好处是只要加载一次
private static Map<String,BeanConfig> cache=new HashMap<>();
//静态块进行处理数据添加--直接使用静态块一次性加载
static {
try {
//
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("beans.xml");
//获取根元素
Element rootElement = document.getRootElement();
//获取所有的bean元素,当前子元素不止一个,使用list
List<Element> allBeanElement = rootElement.elements("bean");
//遍历集合
for (Element beanEle : allBeanElement) {
//外层的bean的属性
String id = beanEle.attributeValue("id");
String className = beanEle.attributeValue("className");
//创建BeanConfig,并且封装id和className
BeanConfig beanConfig = new BeanConfig();
beanConfig.setId(id);
beanConfig.setClassName(className);
//获取子标签property
List<Element> allPropertyElement = beanEle.elements("property");
for (Element propEle : allPropertyElement) {
String name = propEle.attributeValue("name");
String value = propEle.attributeValue("value");
//将name和value保存到BeanConfig中--先拿到property
beanConfig.getProps().setProperty(name, value);
}//内层for循环
//将封装好的数据保存到map集合
cache.put(id, beanConfig);
}//外层for循环--end
System.out.println("初始化数据:" + cache);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//
public static Object getBean(String beanId){
BeanConfig beanConfig=cache.get(beanId);
//判断这个对象是否合法
if (beanConfig==null){
throw new RuntimeException("获得的对象["+beanId+"]不存在");
}
//如果存在--通过反射机制进行获取
try {
String className = beanConfig.getClassName();
Class clazz=Class.forName(className);
//获取实例对象
Object obj = clazz.newInstance();
//循环解析--BeanUtils
//stringPropertyNames()方法是Properties的api中提供的,
// 作用是获取到属性名字的字符串类型
for (String name:beanConfig.getProps().stringPropertyNames()){
//每遍历到一个name,就返回name对应的value
String value=beanConfig.getProps().getProperty(name);
//使用BeanUtils封装数据
BeanUtils.setProperty(obj,name,value);
}
return obj;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
package com.igeek.Dom4j_02;
/**
* @author Lynn
* @create 2020-12-23-14:39
*/
import org.junit.Test;
/**
* 测试类
*/
public class XMLTEst {
@Test
public void test(){
//通过实例化数据的方法获取
User user=(User)BeanFactory.getBean("userId01");
System.out.println(user);
Book book=(Book) BeanFactory.getBean("book02");
System.out.println(book);
}
}