Junit单元测试
测试分类:
1.黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值
2.白盒测试:需要写代码,关注程序具体的执行流程
Junit使用:白盒测试
步骤:
1. 定义一个测试类(测试用例)
建议:
- 测试类名:被测试的类名Test CalculatorTest
- 包名:xxx.xxx.xx.test day01.test
2. 定义测试方法名:可以独立运行
建议:
- 方法名:test测试的方法名 testAdd()
- 返回值:void
- 参数列表:空参
3. 给方法加@Test
4. 导入Junit依赖环境
判定结果
- 红色:失败
- 绿色:成功
- 一般我们会使用断言操作来处理结果
Assert.assertEquals(期望的结果,运算的结果);
补充:
- @Before:修饰的方法会在测试方法之前被自动执行
- @After:修饰的方法会在测试方法执行之后自动被执行
iter 增强for
反射:框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
- 好处:
1.可以在程序运行过程中,操作这些对象
2.可以解耦,提高程序的可扩展性
Java代码在计算机中经历的阶段:三个阶段
1. Source源代码阶段(Person.java--javac编译->Person.class)
2. Class类对象阶段(Person.class--类加载器ClassLoader->Class类对象)
成员变量Field[] fields、构造方法Constructor[] cons、成员方法Method[] methods
3. Runtime运行时阶段(创建对象new Person();)
获取Class对象的方式:
1.Class.forName("全类名"):将字节码文件加载进内存,返回Class对象 (多用于配置文件,将类名定义在配置文件中。读取文件,加载类)
例如: Class cls1 = Class.forName("day01.domain.Person");
2.类名.class:通过类名的属性class获取 (多用于参数的传递)
例如: Class cls2 = Person.class;
3.对象.getClass():getClass()方法在Object类中定义着 (多用于对象的获取字节码的方式)
例如: Person p = new Person();
Class cls3 = p.getClass();
结论:同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
Class对象功能:
获取功能:
1.获取成员变量们
(1)Field[] getFields():获取所有public修饰的成员变量
例如: Class personClass = Person.class;
Field[] fields = personClass.getFields();
(2)Field getField(String name):获取指定名称的public修饰的成员变量
例如: // Person类里的成员变量 public String a;
Field a = personClass.getField("a");
(3)Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
例如: Field[] declaredFields = personClass.getDeclaredFields();
(4)Field getDeclaredField(String name):获取指定名称的成员变量,不考虑修饰符
例如: // Person类里的成员变量 private String d;
Field d = personClass.getDeclaredField("d");
2.获取构造方法们
(1)Constructor<?>[] getConstructors():获取所有public修饰的构造方法
(2)Constructor<T> getConstructor(类<?>...parameterTypes):获取指定参数列表的public修饰的构造方法
例如: /*Person类里的构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}*/
Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
// 空参如下
Constructor<Person> constructor1 = personClass.getConstructor();
(3)Constructor<?>[] getDeclaredConstructors():获取所有的构造,不考虑修饰符
(4)Constructor<T> getDeclaredConstructor(类<?>...parameterTypes):获取指定参数列表的构造方法,不考虑修饰符
3.获取成员方法们
(1)Method[] getMethods():获取所有public修饰的成员方法
(2)Method getMethod(String name, 类<?>...parameterTypes):获取指定名称的public修饰的成员方法
例如: /*Person类里的成员方法
public void eat(){
System.out.println("eat...");
}
public void eat(String food){
System.out.println("eat..." + food);
}
/*
Method eat_method = personClass.getMethod("eat");
Method eat_method2 = personClass.getMethod("eat", String.class);
(3)Method[] getDeclaredMethods():获取所有的成员方法,不考虑修饰符
(4)Method getDeclaredMethod(String name, 类<?>...parameterTypes):获取指定名称的成员方法,不考虑修饰符
4.获取类名
String getName()
例如: String className = personClass.getName();
Field:成员变量
操作:
1.设置值:void set(Object obj, Object value)
例如: // 设置成员变量a的值
Person p = new Person();
a.set(p,"张三");
2.获取值:get(Object obj)
例如: // 获取成员变量a的值
Object value = a.get(p);
3.忽略访问权限修饰符的安全检查:setAccessible(true):暴力反射
例如: d.setAccessible(true);
Constructor:构造方法
创建对象:T newInstance(Object... initargs)
例如: Person person = constructor.newInstance("张三", 23);
注意:如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
例如: Person person2 = personClass.newInstance();
Method:方法对象
执行方法:Object invoke(Object obj, Object... args)
例如: Person p = new Person();
eat_method.invoke(p);
eat_method2.invoke(p,"饭");
获取方法名称:String getName()
例如: String name = method.getName();
反射案例练习
需求:写一个“框架”,不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
实现:
1.配置文件
2.反射
步骤:
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2.在程序中加载读取配置文件
3.使用反射技术来加载类文件进内存
4.创建对象
5.执行方法
// 配置文件pro.properties
className=day01.domain.Student
methodName=sleep
public class ReflectTest {
public static void main(String[] args) throws Exception {
// 1.加载配置文件
// 1.1创建Properties对象
Properties pro = new Properties();
// 1.2加载配置文件,转换为一个集合
// 1.2.1获取class目录下的配置文件
ClassLoader classLoader = ReflectTest.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");
pro.load(is);
// 2.获取配置文件中定义的数据
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
// 3.加载该类进内存
Class<?> cls = Class.forName(className);
// 4.创建对象
Object obj = cls.newInstance();
// 5.获取方法对象
Method method = cls.getMethod(methodName);
// 6.执行方法
method.invoke(obj);
}
}