当前位置:网站首页 > Java基础 > 正文

java基础的测试



1、概念介绍

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。单元是人为规定的最小的被测功能模块。

本文主要讲Java中的单元测试中的代码编写,一般最小的单元就是一个方法,设计测试场景(一些边界条件),看运行结果是否满足预期,修改了代码也能帮助验证是否影响了原有的逻辑。

2、常用的Java测试框架

Junit:是一个为Java编程语言设计的单元测试框架。

Mockito:允许程序员使用自动化的单元测试创建和测试模拟对象。

PowerMock:PowerMock利用自定义的类加载器和字节码操纵器,来确保静态方法的模拟、静态初始化的删除、函数构造、最终的类和方法以及私有方法。

实际上还有许多优秀的测试框架,这几种笔者比较常用,所以本文记录下使用方法。

3、Maven引入

相关的Maven依赖如下

 

彼此间有版本对应关系,没对应可能会出现冲突,其官网的版本对应关系如下:

github的Wiki地址:https://github.com/powermock/powermock/wiki/Mockito

4、自动生成单元测试代码

  • Idea引入插件

  • 选择要生成单元测试的类,按Alt+Insert出现如下界面,选择TestMe自动生成文件

  • 选择需要的生成模板,可以根据自己实际引入的依赖选择,此处选择Junit4+Mockito

  • 生成的代码如下,可以生成一些基本的方法和注解,然后根据实际情况修改,可以节省一部分工作量。

5、常用注解和配置

@Mock:创建一个模拟的对象,类似于@Autowired,但不是真实的对象,是Mock对象,这个注解使用在类属性上

@InjectMocks:创建一个实例,其余用@Mock注解创建的mock将被注入到用该实例中,这个注解使用在类属性上

@RunWith:表示一个运行器,@RunWith(PowerMockRunner.class)表示指定用PowerMockRunner运行,这个注解使用在类上

@PowerMockIgnore:这个注解表示将某些类延迟到系统类加载器加载,解决一些类加载异常。(具体类加载异常实际中还未遇见,后续补充),这个注解在类和方法上使用

@PrepareForTest:这个注解告诉PowerMock为测试准备某些类,通常是那些需要字节码操作的类。这包括带有final、private、static或native方法的类,new一个对象时,需要特殊处理(见下面的whenNew),这个注解在类和方法上使用

@Test:@Test修饰的public java基础的测试 void方法可以作为测试用例运行。Junit会构造一个新的类实例,然后调用所有加了@Test的方法,方法执行过程中的任何异常,都会被判定为测试用例执行失败。

@Before:@Before注解的方法中的代码会在@Test注解的方法中首先被执行。可以做一些公共的前置操作:加入一些申请资源的代码:申请数据库资源,申请io资源,申请网络资源,new一些公共的对象等等。

@After:@After注解的方法中的代码会在@Test注解的方法中首先被执行。可以做一些公共的后置操作,如关闭资源的操作。

注:可以查看注解上的注释,了解其大致用法。

6、常规用法

下面给一个使用上述所有注解的简单例子:

 

运行结果如下:

被单元测试的方法源码如下:

 
 

6.1、when().thenReturn()

当调用mock对象的方法时,根据入参条件,返回指定的值。只调用一次thenReturn(),则调用mock方式时始终返回相同的值;如果多次thenReturn(),可以在调用同一方法时,根据调用次数返回不同的值,如下:

 

6.2、whenNew().thenReturn()和verifyNew()

当需要new一个对象时,可以根据条件返回一个mock对象,下面的示例,当new File()时,如果入参是path,则返回mock的文件对象。注意:需要new 一个mock对象时,需要将 被测试类(@InjectMocks修饰的类)放入到@PrepareForTest注解中。

示例代码如下:

 

注意:verifyNew()只能验证预期的对象创建,就是whenNew的对象次数,不是真实的对象创建次数,即如果该对象没有被mock,而是真实的创建对象,则次数不会被统计。

verifyNew()时需要将@InjectMocks修饰的类放入@PrepareForTest注解中,如下图:

6.3、Mockito.verify()

  • 验证中间过程的方法入参是否符合预期,例如中间某个方法的入参经过了计算得到,则可以验证此入参是否符合预期
 
  • 验证中间过程的方法被调用的次数是否符合预期
 

6.4、PowerMockito.doNothing().when()

mock无返回值的方法

 

6.5、PowerMockito.method()和Whitebox.invokeMethod()

mock私有方法,有两种方式,代码如下:

方式一:

 

方式二:

 

6.6、PowerMockito.mockStatic()和verifyStatic()

mock静态方法,需要注意将调用的静态方法的类放入@PrepareForTest注解,如下图:

代码如下:

 

6.7、PowerMockito.verifyPrivate()

验证私有方法调用次数,被测试方法调用自身的私有方法,有时候需要统计次数,则可以采用verifyPrivate()

注意:只有spy的对象才能验证私有方法的调用次数,mock的对象不行。doReturn和thenReturn的区别在于,doReturn不会进入到方法里面直接返回,thenReturn会先走方法再返回

 

7、总结

其实在正常的单元测试中,可能一个方法会很复杂,里面会同时包含很多种情形,这时候需要我们灵活组合,一些基本的操作在上面都能找到,能满足大部分需求。doAnswer用于修改指定方法的逻辑可以自定义,doThrow用来抛出异常,覆盖异常场景,还有一些其他的操作,这里暂不写,后续有空补上。

8、问题补充

8.1、Mock无返回值的静态方法

mock静态方法,需要注意将调用的静态方法的类放入@PrepareForTest注解,如下图:

方式一:

 

方式二:

 

第二种方式,在方法调用时,入参如果用到any()匹配,可能会抛出 InvalidUseOfMatcherException,可以在方法入参上加参数匹配器,如下:

 

方式三(补充)

其实mock静态无返回值的方法,只需要将静态方法的类放入@PrepareForTest注解,然后mockStatic()对应的类即可,不需要显示的mock其方法,如下:

 

8.1、Mock被final修饰的类

同mock静态方法类似,需要注意将mock的类放入@PrepareForTest注解,如下图:

mock final修饰的类很简单,方法如下

  • 上一篇: java基础可以干嘛
  • 下一篇: 复习java基础
  • 版权声明


    相关文章:

  • java基础可以干嘛2025-04-21 23:42:03
  • java的基础数组2025-04-21 23:42:03
  • java基础 pdf2025-04-21 23:42:03
  • java金融基础2025-04-21 23:42:03
  • 基础代码java2025-04-21 23:42:03
  • 复习java基础2025-04-21 23:42:03
  • 数学零基础自学java2025-04-21 23:42:03
  • 如何面试java基础2025-04-21 23:42:03
  • java基础3002025-04-21 23:42:03
  • java基础分享2025-04-21 23:42:03