文章目录
- [1. 为什么要使用mock](#1. 为什么要使用mock)
- [2. Mock 方法](#2. Mock 方法)
- [3. 验证和断言](#3. 验证和断言)
- [4. 给对象打桩](#4. 给对象打桩)
- [5. @Mock 注解](#5. @Mock 注解)
- [6. @BeforeEach 和 @AfterEach](#6. @BeforeEach 和 @AfterEach)
- [7. Spy 方法 和 @Spy 注解](#7. Spy 方法 和 @Spy 注解)
1. 为什么要使用mock
- Mock可以理解为创建一个虚假的对象,或者说模拟出一个对象,在测试环境中用来替换掉真实的对象,以达到:
- 验证该对象的某些方法的调用情况,调用了多少次,参数是多少
- 给这个对象的行为做一个定义,来指定返回结果或者指定特定的动作
2. Mock 方法
- mock方法来自
org.mockito.Mock
,它表示可以mock
一个对象或者是接口
java
publie static <T> T mock(Clas<T> classToMock)
1、classToMock
:待 mock 对象的 class 类
2、返回mock
出来的类
- 实例:使用 mock 方法 mock 一个类
java
Random random = Mockito.mock(Random.class);
System.out.println(random.nextInt()); //这里表示调用了一次,等同于如下 只验证一次
// 验证模拟的 random 对象 是否用到了 nextInt 方法,后面也可以接模拟对象调用的次数
Mockito.verify(random, Mockito.times(1)).nextInt(); // 0
- 如上不对其行为进行定义的话,则 mock 对象方法返回值为返回类型的默认值,所以上面的案例只返回
0
(int 默认值为 0)
3. 验证和断言
- 验证是校验待验证的对象是否发生过某些行为,
Mockito
中验证的方法是:verify
java
verify(mock).someMethod("some arg");
verify(mock, times(1)).someMothod("some arg");
- 使用
verify
验证: verify
配合time()
方法,可以校验某些操作发生的次数
java
@Test
void check() {
Random random = Mockito.mock(Random.class, "test1");
System.out.println(random.nextInt());
System.out.println(random.nextInt());
Mockito.verify(random, Mockito.times(2));
}

- 断言使用的类是
Assertions
java
Random random = Mockito.mock(Random.class, "test1");
Assertions.assertEquals(100, random.nextInt());

- 当使用 Mock 对象时,如果不对其行为进行定义,则 mock 对象方法的返回值为返回类型的默认值
4. 给对象打桩
- 打桩的意思是给 mock 对象规定一行的行为,使其按照我们的要求来执行具体的操作
- 给
nextInt()
打桩
java
Random random = Mockito.mock(Random.class, "test1");
// 当 random 对象执行 nextInt 方法,永远返回 100
Mockito.when(random.nextInt()).thenReturn(100);
// 第一个参数表示 期待值,第二个参数表示 实际值
Assertions.assertEquals(100, random.nextInt());
- 把上面断言的期待值改为
101
,就会报异常了
5. @Mock 注解
- 可以理解为:快速创建 mock 的方法,可以使用
@mock
注解更为方便 - 注意:Mock 注解需要搭配
MockitoAnnotations.initMocks(testClass)
方法一起使用
老版本搭配的方法:MockitoAnnotations.initMocks(testClass);
java
@Mock
private Random random;
等价于
Random random = Mockito.mock(Random.class);
- 上面的案例可以改为:
java
@Mock
private Random random;
@Test
void check() {
MockitoAnnotations.initMocks(this);
Mockito.when(random.nextInt()).thenReturn(100);
Assertions.assertEquals(100, random.nextInt());
}
6. @BeforeEach 和 @AfterEach
- 在 Junit 5 的,
@Before
和@After
注解被@BeforeEach
和@AfterEach
所替代
java
@BeforeEach
void before() {
System.out.println("---测试前准备---");
}
@Test
void check() {
MockitoAnnotations.initMocks(this);
Mockito.when(random.nextInt()).thenReturn(100);
Assertions.assertEquals(100, random.nextInt());
}
@AfterEach
void afeter() {
System.out.println("---测试结束 ---");
}

7. Spy 方法 和 @Spy 注解
- spy 方法 和 mock 方法的不同点:
- 被 spy 的对象会走真实的方法,而 mock 对象不会,mock 对象
- spy() 方法的参数是对象实例,mock 的参数是 class
- 使用 spy 方法案例:
java
@Spy
private Demo random;
@BeforeEach
void before() {
// 执行初始化
MockitoAnnotations.initMocks(this);
}
@Test
void check() {
// 没有打桩,random 执行的就是真实的方法
Assertions.assertEquals(100, random.add(1,2));
}
java
@Test
void check() {
// 打桩后,执行的就是打桩的方法
Mockito.when(random.add(1,2)).thenReturn(3);
Assertions.assertEquals(100, random.add(1,2));
}