Mockito 模拟示例

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 示例。

Published At
Categories with 技术
Tagged with
comments powered by Disqus