前言
在计算机编程中,单元测试是一种软件测试方法,通过该方法可以测试源代码的各个单元功能是否适合使用。为代码编写单元测试有很多好处,包括可以及早的发现代码错误,促进更改,简化集成,方便代码重构以及许多其它功能。
使用 Java 语言的朋友应该用过或者听过 Junit 就是用来做单元测试的,那么为什么我们还需要 Mockito 测试框架呢?想象一下这样的一个常见的场景,当前要测试的类依赖于其它一些类对象时,如果用 Junit 来进行单元测试的话,我们就必须手动创建出这些依赖的对象,这其实是个比较麻烦的工作。
此时就可以使用 Mockito 测试框架来模拟那些依赖的类,这些被模拟的对象在测试中充当真实对象的虚拟对象或克隆对象,而且 Mockito 同时也提供了方便的测试行为验证。这样就可以让我们更多地去关注当前测试类的逻辑,而不是它所依赖的对象。
生成 Mock 对象方式
要使用 Mockito,首先需要在我们的项目中引入 Mockito 测试框架依赖,基于 Maven 构建的项目引入如下依赖即可:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>
如果是基于 Gradle 构建的项目,则引入如下依赖:
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.3.3'
使用 Mockito 通常有两种常见的方式来创建 Mock 对象。
1、使用 Mockito.mock(clazz) 方式
通过 Mockito 类的静态方法 mock 来创建 Mock 对象,例如以下创建了一个 List 类型的 Mock 对象:
List<String> mockList = Mockito.mock(ArrayList.class);
由于 mock 方法是一个静态方法,所以通常会写成静态导入方法的方式,即 List<String> mockList = mock(ArrayList.class)。
2、使用 @Mock 注解方式
第二种方式就是使用 @Mock 注解方式来创建 Mock 对象,使用该方式创需要注意的是要在运行测试方法前使用
MockitoAnnotations.initMocks(this) 或者单元测试类上加上 @ExtendWith(MockitoExtension.class) 注解,如下所示代码创建了一个 List 类型的 Mock 对象(PS: @BeforeEach 是 Junit 5 的注解,功能类似于 Junit 4 的 @Before 注解。):
/**
* @author mghio
* @date: 2020-05-30
* @version: 1.0
* @description:
* @since JDK 1.8
*/
//@ExtendWith(MockitoExtension.class)
public class MockitoTest {
@Mock
private List<String> mockList;
@BeforeEach
public void beforeEach() {
MockitoAnnotations.initMocks(this);
}
}
验证性测试
Mockito 测试框架中提供了 Mockito.verify 静态方法让我们可以方便的进行验证性测试,比如方法调用验证、方法调用次数验证、方法调用顺序验证等,下面看看具体的代码。
验证方法单次调用
验证方法单次调用的话直接 verify 方法后加上待验证调用方法即可,以下代码的功能就是验证 mockList 对象的 size 方法被调用一次。
/**
* @author mghio
* @date: 2020-05-28
* @version: 1.0
* @description:
* @since JDK 1.8
*/
@ExtendWith(MockitoExtension.class)
public class MockitoVerifyTest {
@Mock
List<String> mockList;
@Test
void verify_SimpleInvocationOnMock() {
mockList.size();
verify(mockList).size();
}
}
验证方法调用指定次数
除了验证单次调用,我们有时候还需要验证一些方法被调用多次或者指定的次数,那么此时就可以使用 verify + times 方法来验证方法调用指定次数,同时还可以结合 atLeast + atMost 方法来提供调用次数范围,同时还有 never 等方法验证不被调用等。
/**
* @author mghio
* @date: 2020-05-28
* @version: 1.0
* @description:
* @since JDK 1.8
*/
@ExtendWith(MockitoExtension.class)
public class MockitoVerifyTest {
@Mock
List<String> mockList;
@Test
void verify_NumberOfInteractionsWithMock() {
mockList.size();
mockList.size();
verify(mockList, times(2)).size();
verify(mockList, atLeast(1)).size();
verify(mockList, atMost(10)).size();
}
}
验证方法调用顺序
同时还可以使用 inOrder 方法来验证方法的调用顺序,下面示例验证 mockList 对象的 size、add 和 clear 方法的调用顺序。