1.1 测试

测试分类:

  • 黑盒测试:不看代码,进行输入参数,查看输出结果是否符合要求
  • 白盒测试:能够参考代码执行过程

步骤
1.定义一个测试类(测试用例)

建议:测试类名:被测试的类名+Test: CalculatorTest 包名:xxx.xxx.xx.test: cn.itcast.test

2.定义测试方法:可以独立运行

建议:方法名:test+测试的方法名: testAdd() 返回值:void 参数列表:空参

3.给方法加@Test
4.倒入Junit的依赖文件
结果
绿色:成功
红色:失败
一般会使用断言操作来处理结果
Assert.assertEquals(expected,result);
*断言

  1. //3断言,断言结果为3
  2. Assert.assertEquals(3,result);
  3. //期望值为3,真实值为result
  4. 结果:
  5. java.lang.AssertionError:
  6. Expected :3
  7. Actual :-1
  8. <Click to see difference>

补充
@Before:
修饰的方法会在测试方法之前被自动执行
@After:
修饰的方法会在测试方法执行之后自动被执行

  1. /*
  2. * 初始化方法:
  3. * 用于资源申请,所有测试方法在执行之前都会先执行该方法
  4. */
  5. @Before
  6. public void init(){
  7. System.out.println("init....");
  8. }
  9. /*
  10. * 释放资源都方法:
  11. * 在所有测试方法执行完成后,都会自动执行该方法
  12. */
  13. @After
  14. public void close(){
  15. System.out.println("closed...");
  16. }

1.2 反射

反射也被成为 “框架设计的灵魂”
框架:半成品软件
可以在框架的基础上进行软件开发,简化编码。
概念
将类的各个组成部分封装为其他对象,这就是反射机制
好处

  1. 在程序的运行过程中操作一些对象(Class对象阶段的Class对象)

例如:通过InteliJ软件可以在写代码的阶段调用各种方法
截屏2020-07-27 09.58.23.png

  1. 可以解耦,降低程序耦合性,提高程序的可拓展性

    获取Class的三种方式

  2. class.forName(“全类名”):将字节码文件加载进内存,返回class对象

    Tips:全类名是指:包名+类名,例如:code.junit.domain.Person 该方法多用于配置文件,将类名定义在配置文件中,读取文件,加载类

  3. 类名.class : 通过类名的属性class来获取

    该方法多用于参数的传递

  4. 对象.getClass():getClass()方法在Object类中定义

    多用于对象的获取字节码的方式

创建一个Person类

  1. public class Person {
  2. private String name;
  3. private int age;
  4. //....省略构造方法和getset
  5. }

  1. public class ReflectDemo01 {
  2. public static void main(String[] args) throws ClassNotFoundException {
  3. //1.Class.forName
  4. Class<?> cls1 = Class.forName("code.junit.domain.Person");
  5. System.out.println(cls1);//class code.junit.domain.Person
  6. //2.类名.Class
  7. Class cls2=Person.class;
  8. System.out.println(cls2);//class code.junit.domain.Person
  9. //3.对象.getClass()
  10. Person p=new Person();
  11. Class cls3=p.getClass();
  12. System.out.println(cls3);//class code.junit.domain.Person
  13. //==比较三个对象
  14. System.out.println(cls1 == cls2);//true
  15. System.out.println(cls1 == cls3);//true
  16. }
  17. }

结论
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪种方法获得的class文件都是同一个

Class对象功能

*获取功能

  1. 获取成员变量们

Field[] getFields() :获取所有public修饰的成员变量
Field getField(String name) :获取指定名称的public修饰的成员变量
Field[] getDeclaredFields() :获取所有成员变量,不考虑修饰符
Field getDeclaredField(String name)

  1. 获取构造方法们

Constructor<?>[] getConStructors()
Constructor<T> getConstructor(类<?> ... parameterTypes)
Constructor<?>[] getDeclaredConStructors()
Constructor<T> getDeclaredConstructor(类<?> ... parameterTypes)

  1. 获取成员方法们

Method[] getMethods()
Method getMethod(String name, 类<?>... parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, 类<?>... parameterTypes)

  1. 获取类名

String getName()

成员变量
操作:
1.设置值: void set(Object obj,Object value) :obj是指成员所在的对象名
2.获取值: get (Object obj) :obj是值该成员变量所在的对象名
3.忽略访问权限修饰符的安全检查(暴力反射)
setAccessible(true)

  1. public static void main(String[] args) throws Exception {
  2. //1 获取Person的class对象
  3. Class<Person> cls = Person.class;
  4. // 获取成员变量:
  5. Field[] fields = cls.getFields();
  6. for (Field field : fields) {
  7. System.out.println(field);
  8. }
  9. System.out.println("-----------");
  10. Field a = cls.getField("a");
  11. System.out.println(a);
  12. //获取成员变量a的值
  13. Person p = new Person();
  14. Object value = a.get(p);
  15. System.out.println(value);//null
  16. //设置值
  17. a.set(p,"雨落");
  18. System.out.println(p.a);//雨落
  19. System.out.println("----------");
  20. Field[] declaredFields = cls.getDeclaredFields();
  21. for (Field f : declaredFields) {
  22. System.out.println(f);
  23. }
  24. System.out.println("-----------");
  25. Field d = cls.getDeclaredField("d");
  26. //忽略访问权限修饰符的安全检查
  27. d.setAccessible(true);//暴力反射
  28. Object value2 = d.get(p);
  29. System.out.println(value2);//null
  30. }

构造方法:
创建对象
T newInstance(Object... initargs) initargs:参数

  1. //1 获取Person的class对象
  2. Class<Person> cls = Person.class;
  3. //获取构造方法
  4. Constructor<Person> constructor = cls.getConstructor(String.class, int.class);
  5. System.out.println(constructor);
  6. //创建对象
  7. Object person = constructor.newInstance("雨落", 19);
  8. System.out.println(person);
  9. //输出:
  10. //public code.junit.domain.Person(java.lang.String,int)
  11. //Person{name='雨落', age=19}
  12. System.out.println("---------");
  13. Constructor<Person> constructor1 = cls.getConstructor();//空参
  14. System.out.println(constructor1);
  15. //创建对象
  16. Object person1 = constructor1.newInstance();//空参
  17. System.out.println(person1);
  18. //输出:
  19. //public code.junit.domain.Person()
  20. //Person{name='null', age=0}

如果使用空参数构造方法创建对象,操作可以简化:Class对象的 newInstance 方法

  1. //1 获取Person的class对象
  2. Class<Person> cls = Person.class;
  3. Object o = cls.newInstance();
  4. System.out.println(o);