今日内容
单元测试
测试概述
在我们编写代码的时候,开发了很多功能,我们需要对这些已经开发好的功能提前进行测试,检测功能方法是否有漏洞,是否有bug,这个时候我们可以使用Junit单元测试对我们开发的代码进行测试。
Junit是Java语言的单元测试框架,属于第三方的一个工具,一般情况下我们需要导入相应的jar包,对于目前使用的集成开发工具自带的,我们今天是以Idear开发工具为主
Junit属于白盒测试
测试分类
-
黑盒测试:大多数测试的细节隐藏起来,通常使用的一些软件进行测试
-
白盒测试:大多数是需要写一些代码进行测试,我们能够看到一些测试的流程。
-
Junit使用
-
步骤
-
下载一个Junit对应的版本jar包
-
添加jar依赖到工程里面
-
定义一个测试类
-
建议:
-
测试类名:被测试的类Test 如:UserTest、PeopleTest、CalculatorTest....
-
测试类:应该放到测试资源包中
-
测试包:xxx.xxx.test 如:com.zhiyou100.test.user
-
-
定义测试方法:可以实现独立运行 Junit4/Junit5
-
建议:
-
方法名:test被测试的功能方法名 如:testGetName()、testAddNum()
-
返回值:void
-
参数列表:Junit4中-->空参 Junit5--->可以携带
-
修饰符:一般Junit4中使用public Junit5中使用范围较广
-
-
-
-
-
-
给方法上添加注解@Test
-
-
结果判定
-
红色--->测试失败,中间可能出现了异常
-
橘黄色 ---> 测试失败 实际的值和我们期望的值不一致
-
绿色 --->测试成功
-
一般情况下,我们都是使用断言(Assert)操作来处理结果的
示例代码:
Assert.assertEquals(期望的值,实际的值);
-
-
Junit的其他测试相关的注解:
JUnit4中:
-
@Test 把一个方法标记为测试方法
-
@Before 每一个测试方法执行前会自动调用一次该方法(搭配@Test一起使用)
-
@After 每一测试方法执行后会自动调用一次该方法(搭配@Test一起使用)
-
@BeforeClass 所有的测试方法执行前执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
-
@AfterClass 所有的测试方法执行后执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
-
@Ignore 暂不执行该测试方法(待定的) (搭配@Test一起使用)
Junit5中:
-
@Test 把一个方法标记为测试方法
-
@BeforeEach 每一个测试方法执行前会自动调用一次该方法(搭配@Test一起使用)
-
@AfterEach 每一测试方法执行后会自动调用一次该方法(搭配@Test一起使用)
-
@BeforeAll 所有的测试方法执行前执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
-
@AfterAll 所有的测试方法执行后执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
-
@Disabled 暂不执行该测试方法(待定的) (搭配@Test一起使用)
-
......
-
-
静态导入
JDK5之后出现的新特性,只要在import后面加上关键字static,就可以把后面类的static修饰的变量和方法导入到本类中。调用的时候和调用本类中的静态成员没有区别。
-
静态导入格式:import static 包名.类名.静态成员名 ----> import static 包名.类名.*
-
注意事项:
-
方法必须是静态的
-
如果有多个静态方法重名,添加前缀,即添加类名
-
-
-
@Test属性操作
-
expected属性 期望测试中携带有异常信息,格式 @Test(expected = NullPointerException.class)
如果出现异常,测试成功,如果未出现异常,测试失败
-
timeout属性,用来测试方法的执行时间 格式 @Test(timeout=5),单位为毫秒值,如果运行时间在设置值之内,则测试成功,如果超出了设置值范围,则测试失败。
-
反射
-
动态语言
是一类可以在程序运行过程中改变其结构的语言。比如说定义的方法、对象、一些功能代码可以在程序运行中被加载进去,从而达到修改或者删除已有的方法和数据
动态语言:JavaScript(脚本语言)、PHP 、Python、C#等等
-
静态语言
与动态语言相比,运行时程序结构不发生改变的语言就是静态语言。 如C、C++、Java等
Java虽不是动态语言,但是称之为“准动态语言”,可以利用反射机制来动态的获取类结构信息并且修改类结构信息。Java的动态性使开发更加灵活。
反射概述
-
Reflection,在程序中主要是借助Reflection API获取类结构的内部信息,并且能够直接操作类结构内部信息(属性和方法) 如:Class.forName("com.mysql.jdbc.Driver");// 硬编码
-
类加载进内存后,在堆存当中就产生了一个Class类型对象(一个类在内存当中有且只有一个Class对象),这个对象就包含了完整的类的结构信息。(属性、方法、构造方法、类名、静态信息等等)。我们可以通过这个对象看到类的内部结构。这个对象就像一面镜子一样。透过这个镜子可以看到类的内部结构。这种形式,我们形象的称之为“反射机制”。
-
反射一般把它当成框架的灵魂
框架:半成品软件,我们可以在框架的基础上进行开发,简化代码
-
好处:
-
可以在程序运行过程中 ,动态的操作这些对象
-
可以达到解耦,提高程序的可扩展性。
-
-
借助于Class类、Method类、Filed类、Constructor类实现反射
-
反射常用API操作
获取Class对象:有三种方式
-
Class.forName("类的全路径"):将字节码文件加载进内存当中,返回Class对象
-
多用于读取配置文件 xml/properties,将类名,方法名,用户名等等配置到文件中
-
-
类名.class :通过类名的属性class获取Class对象
-
多用于参数传递
-
-
对象.getClass():通过getClass()方法获取Class对象,getClass() 是Object类中的方法
-
常用于获取对应的字节码对象
-
-
总结:不论是通过哪种方式获取到的,同一个字节码文件在一次程序运行过程中,只会生成一个Class对象
Method对象、Field对象、Constructor对象
属性对象
-
获取属性对象
-
Field getField(String name) 返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。
-
Field[] getFields() 返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。
-
Field getDeclaredField(String name) 返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。 不限制权限修饰符
-
Field[] getDeclaredFields() 返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。 不限制权限修饰符
-
-
设置属性对象值
void set(Object obj,Object value):第一个参数是对应的实际对象,第二个参数是需要设置的值
-
获取属性对象值
Object get(Object obj) : 获取对应的属性值
-
忽略访问权限修饰符的安全性检查:关闭访问权限
setAccessiable(boolean flag) 传入true值,关闭访问权限,传入false值,打开访问权限
构造对象
-
获取构造对象
-
Constructor<T> getConstructor(类<?>... parameterTypes) 返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。
-
Constructor<?>[] getConstructors() 返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。
-
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) 返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。
-
Constructor<?>[] getDeclaredConstructors() 返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类
-
-
构建对象
T newInstance(Object ... initargs)
-
如果想使用空参构造,有两种方式:
第一种可以使用Class类中newInstance() 第二种可以使用Constructor类中的newInstance()
通常使用第一种方式。
方法对象
-
获取方法对象
-
Method getMethod(String name, 类<?>... parameterTypes) 返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
-
Method[] getMethods() 返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。
-
Method getDeclaredMethod(String name, 类<?>... parameterTypes) 返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。
-
Method[] getDeclaredMethods() 返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
-
-
执行方法
-
Object invoke(Object obj,Class ... parametertype)
-
-
获取方法的名称
-
String getName()
-
类加载过程
注解
注解概述
我们可以把注解理解为一种代码级别的说明,功能性说明,是从JDK1.5之后引入的新特性,格式:@注解名称
对比注释,是给开发者看的,带代码没有任何影响,注解,是给JVM看的,具有功能的代码。
-
定义:也叫元数据,是一种具有代码级别的说明,它同接口、类、枚举是在同一层次上。它可以声明在类、方法、属性、包、局部变量、方法参数等上面,用来对这些元素进行说明,注释。
-
本质:就是一个接口,该接口默认继承Annotation接口。
注解的作用
在目前的主流应用中主要是替代配置文件(如xml文件)
-
在Servlet2.5之前不支持注解开发,从Servlet3.0开始支持注解开发,不再需要到web.xml文件中去注册Servlet信息
-
优点:开发效率高,代码精简度高
-
缺点:代码耦合性太强了,维护困难。
常见的内置注解(原生)
-
@Override:是在java.lang包中,告知编译期此方法是重写父类中的方法
-
@SuppressWarning:是在java.lang包中,告知编译期此处内部有风险,抑制编译时的警告信息。
-
此注解需要搭配参数/属性才可以使用
-
参数/属性的名称是value,参数类型是String[]
-
unused : 未使用
-
unchecked :未检查(强制类型转换时泛型参数使用未指定),使用List、ArraytList等未进行参数化产生的警告
-
deprecation:过时
-
all :抑制所有
-
-
-
@Deprecated:是在java.lang包中,告知编译期此方法是过时的,是不被鼓励的,可能有更好的方法替代了,但是被此注解标记的方法依然可以使用。