Mockito的嘲笑框架提供了不同方法来嘲笑一个类,让我们看看我们可以嘲笑一个类的不同方法,并阻止它的行为。
莫基托·莫克方法
我们可以使用 Mockito 类mock() 方法来创建给定类或接口的模仿对象。
1package com.journaldev.mockito.mock;
2
3import java.util.List;
4
5import static org.mockito.Mockito.*;
6import static org.junit.jupiter.api.Assertions.*;
7import org.junit.jupiter.api.Test;
8
9public class MockitoMockMethodExample {
10
11 @SuppressWarnings("unchecked")
12 @Test
13 public void test() {
14 // using Mockito.mock() method
15 List<String> mockList = mock(List.class);
16 when(mockList.size()).thenReturn(5);
17 assertTrue(mockList.size()==5);
18 }
19
20}
我们正在使用 [JUnit 5]( / 社区 / 教程 / junit5-tutorial)来编写测试案例,并与Mockito一起嘲笑对象。
Mockito @Mock 评论
我们也可以使用 @Mock 注释来嘲笑一个对象。当我们想在多个地方使用嘲笑的对象时,它是有用的,因为我们避免多次调用 mock() 方法。代码变得更加可读,我们可以指定嘲笑的对象名称,在出现错误时将是有用的。
1package com.journaldev.mockito.mock;
2
3import java.util.List;
4
5import static org.junit.jupiter.api.Assertions.*;
6import static org.mockito.Mockito.*;
7
8import org.junit.jupiter.api.BeforeEach;
9import org.junit.jupiter.api.Test;
10import org.mockito.Mock;
11import org.mockito.MockitoAnnotations;
12
13public class MockitoMockAnnotationExample {
14
15 @Mock
16 List<String> mockList;
17
18 @BeforeEach
19 public void setup() {
20 //if we don't call below, we will get NullPointerException
21 MockitoAnnotations.initMocks(this);
22 }
23
24 @SuppressWarnings("unchecked")
25 @Test
26 public void test() {
27 when(mockList.get(0)).thenReturn("JournalDev");
28 assertEquals("JournalDev", mockList.get(0));
29 }
30
31}
Mockito @InjectMocks 评论
当我们想将被嘲笑的对象注入另一个被嘲笑的对象时,我们可以使用 @InjectMocks 注释。
1package com.journaldev.mockito.mock;
2
3import java.util.List;
4
5import static org.junit.jupiter.api.Assertions.*;
6import static org.mockito.Mockito.*;
7
8import org.junit.jupiter.api.BeforeEach;
9import org.junit.jupiter.api.Test;
10import org.mockito.InjectMocks;
11import org.mockito.Mock;
12import org.mockito.MockitoAnnotations;
13
14public class MockitoInjectMockAnnotationExample {
15
16 @Mock
17 List<String> mockList;
18
19 //@InjectMock creates an instance of the class and
20 //injects the mocks that are marked with the annotations @Mock into it.
21 @InjectMocks
22 Fruits mockFruits;
23
24 @BeforeEach
25 public void setup() {
26 //if we don't call below, we will get NullPointerException
27 MockitoAnnotations.initMocks(this);
28 }
29
30 @SuppressWarnings("unchecked")
31 @Test
32 public void test() {
33 when(mockList.get(0)).thenReturn("Apple");
34 when(mockList.size()).thenReturn(1);
35 assertEquals("Apple", mockList.get(0));
36 assertEquals(1, mockList.size());
37
38 //mockFruits names is using mockList, below asserts confirm it
39 assertEquals("Apple", mockFruits.getNames().get(0));
40 assertEquals(1, mockFruits.getNames().size());
41
42 mockList.add(1, "Mango");
43 //below will print null because mockList.get(1) is not stubbed
44 System.out.println(mockList.get(1));
45 }
46
47}
48
49class Fruits{
50 private List<String> names;
51
52 public List<String> getNames() {
53 return names;
54 }
55
56 public void setNames(List<String> names) {
57 this.names = names;
58 }
59
60}
Mockito spy() 用于部分嘲笑
如果我们只想嘲笑特定的行为,并将实际方法称为不受干扰的行为,那么我们可以使用Mockito spy()方法创建一个间谍对象。
1package com.journaldev.mockito.mock;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4import static org.mockito.Mockito.spy;
5import static org.mockito.Mockito.when;
6
7import java.util.ArrayList;
8import java.util.List;
9
10import org.junit.jupiter.api.Test;
11
12public class MockitoSpyMethodExample {
13
14 @Test
15 public void test() {
16 List<String> list = new ArrayList<>();
17 List<String> spyOnList = spy(list);
18
19 when(spyOnList.size()).thenReturn(10);
20 assertEquals(10, spyOnList.size());
21
22 //calling real methods since below methods are not stubbed
23 spyOnList.add("Pankaj");
24 spyOnList.add("Meghna");
25 assertEquals("Pankaj", spyOnList.get(0));
26 assertEquals("Meghna", spyOnList.get(1));
27 }
28
29}
Mockito @Spy 评论
我们可以使用 @Spy 注释来间谍对象,让我们来看看一个简单的例子。
1package com.journaldev.mockito.mock;
2
3import static org.junit.jupiter.api.Assertions.*;
4import static org.mockito.Mockito.*;
5
6import org.junit.jupiter.api.BeforeEach;
7import org.junit.jupiter.api.Test;
8import org.mockito.MockitoAnnotations;
9import org.mockito.Spy;
10
11public class MockitoSpyAnnotationExample {
12
13 @Spy
14 Utils mockUtils;
15
16 @BeforeEach
17 public void setup() {
18 MockitoAnnotations.initMocks(this);
19 }
20
21 @Test
22 public void test() {
23 when(mockUtils.process(1, 1)).thenReturn(5);
24 //mocked method
25 assertEquals(5, mockUtils.process(1, 1));
26 //real method called since it's not stubbed
27 assertEquals(20, mockUtils.process(19, 1));
28
29 }
30
31}
32
33class Utils{
34 public int process(int x, int y) {
35 System.out.println("Input Params = "+x+","+y);
36 return x+y;
37 }
38}
请注意, @Spy 注释试图调用 no-args constructor来初始化被嘲笑的对象。
1org.mockito.exceptions.base.MockitoException: Unable to initialize @Spy annotated field 'mockUtils'.
2Please ensure that the type 'Utils' has a no-arg constructor.
3 at com.journaldev.mockito.mock.MockitoSpyAnnotationExample.setup(MockitoSpyAnnotationExample.java:18)
另外,请注意,Mockito 无法实例化内部类、本地类、抽象类和接口,因此,提供一个可以间谍的实例总是是一个好主意。
1@Spy
2List<String> spyList;
您会注意到,当您调用add()
或get()
方法时,实际方法不会被调用。
1@Spy
2List<String> spyList = new ArrayList<>();
摘要
Mockito 嘲笑框架允许我们通过不同的方法和注释轻松创建模糊对象,我们也可以将模糊对象注入到另一个模糊对象中,这是一个非常有用的功能。
您可以从我们的 GitHub 存储库中查看更多 Mockito 示例。