Mockito 教程

Mockito 是一个基于 Java 的模仿框架,与其他测试框架(如 JUnitTestNG一起使用,它内部使用 Java Reflection API,并允许创建服务的对象。

马克思 教程

对于Mockito教程,我们将使用JUnit 5并创建一些服务来嘲笑。

Mockito Maven 依赖性

若要在项目中实施基于 Mockito 的测试案例,请将以下依赖性添加到项目的 pom.xml 文件中:

 1<dependency>
 2     <groupId>org.mockito</groupId>
 3     <artifactId>mockito-core</artifactId>
 4     <version>2.19.0</version>
 5     <scope>test</scope>
 6</dependency>
 7<dependency>
 8     <groupId>org.mockito</groupId>
 9     <artifactId>mockito-junit-jupiter</artifactId>
10     <version>2.19.0</version>
11     <scope>test</scope>
12</dependency>

请注意,如果您正在使用任何其他测试框架,如 JUnit 4 或 TestNG,则需要使用mockito-junit-jupiter,然后删除这种依赖,并只包括mockito-core依赖。

Mockito Mock 创作

Mockito框架允许我们使用@Mock注释或mock()静态方法创建模拟对象。

Mockito Mock() 方法

下面的示例显示了 mock() 方法的使用:

 1package com.journaldev.mockito;
 2
 3import static org.junit.jupiter.api.Assertions.assertEquals;
 4import static org.mockito.Mockito.when;
 5
 6import org.junit.jupiter.api.Test;
 7import org.mockito.Mockito;
 8
 9import com.journaldev.AddService;
10import com.journaldev.CalcService;
11
12public class CalcService1Test {
13
14    @Test
15    void testCalc() {
16    	System.out.println("**--- Test testCalc executed ---**");
17
18    	AddService addService;
19    	CalcService calcService;
20
21    	addService = Mockito.mock(AddService.class);
22    	calcService = new CalcService(addService);
23
24    	int num1 = 11;
25    	int num2 = 12;
26    	int expected = 23;
27
28    	when(addService.add(num1, num2)).thenReturn(expected);
29
30    	int actual = calcService.calc(num1, num2);
31
32    	assertEquals(expected, actual);
33
34    }
35}

在上面的示例中,我们正在测试CalcService。Mockito.mock() 方法用于创建AddService类的模仿对象。

Mockito Mock 评论

下面的示例显示了 @Mock 注释的使用。

 1package com.journaldev.mockito;
 2
 3import static org.junit.jupiter.api.Assertions.assertEquals;
 4import static org.mockito.Mockito.when;
 5
 6import org.junit.jupiter.api.BeforeEach;
 7import org.junit.jupiter.api.Test;
 8import org.mockito.Mock;
 9import org.mockito.MockitoAnnotations;
10
11import com.journaldev.AddService;
12import com.journaldev.CalcService;
13
14public class CalcService2Test {
15
16    CalcService calcService;
17
18    @Mock
19    AddService addService;
20
21    @BeforeEach
22    public void setup() {
23    	MockitoAnnotations.initMocks(this);
24    }
25
26    @Test
27    public void testCalc() {
28    	System.out.println("**--- Test testCalc executed ---**");
29
30    	calcService = new CalcService(addService);
31
32    	int num1 = 11;
33    	int num2 = 12;
34    	int expected = 23;
35
36    	when(addService.add(num1, num2)).thenReturn(expected);
37
38    	int actual = calcService.calc(num1, num2);
39
40    	assertEquals(expected, actual);
41
42    }
43}

请注意,我们需要拨打MockitoAnnotations.initMocks(这);以初始化用 @Mock、 @Spy、 @Captor 或 @InjectMocks 标注的对象。

Mockito行为验证

要将行为添加到模仿类中,则使用when()thenReturn()函数,这意味着当模仿对象(addService)被调用以添加(num1, num2)参数的方法时,它会返回预期变量中存储的值。

 1public class CalcService {
 2    
 3    private AddService addService;
 4    
 5    public CalcService(AddService addService) {
 6    	this.addService = addService;
 7    }
 8
 9    public int calc(int num1, int num2) {
10    	System.out.println("**--- CalcService calc executed ---**");
11    	return addService.add(num1, num2);
12    }
13
14}

CalcService 依赖于 AddService 类. 它使用 AddService 类的添加方法来执行其操作. 由于我们只想对 CalcService 类进行单元测试,我们必须嘲笑 AddService 实例。

1public interface AddService {
2    public int add(int num1, int num2);
3}
1public class AddServiceImpl implements AddService {
2    @Override
3    public int add(int num1, int num2) {
4    	System.out.println("**--- AddServiceImpl add executed ---**");
5    	return num1 + num2;
6    }
7}

Mockito 查看互动

Mockito 框架会跟踪所有方法调用和它们的参数到模特对象。 Mockito 对模特对象的verify()方法会验证以某些参数调用一种方法。我们还可以指定调用逻辑的数量,例如确切的次数,至少确定的次数,少于指定的次数等。我们可以使用VerificationModeFactory用于调用次数逻辑。 Mockito verify() 方法会检查以正确的参数调用一种方法。

 1package com.journaldev.mockito;
 2
 3import static org.mockito.Mockito.verify;
 4
 5import java.util.List;
 6
 7import org.junit.jupiter.api.Test;
 8import org.mockito.Mockito;
 9import org.mockito.internal.verification.VerificationModeFactory;
10
11public class VerifyInteractionTest {
12    @Test
13    public void testMethod() {
14    	@SuppressWarnings("unchecked")
15    	List<String> mockedList = Mockito.mock(List.class);
16
17    	mockedList.add("first-element");
18    	mockedList.add("second-element");
19    	mockedList.add("third-element");
20    	mockedList.add("third-element");
21    	mockedList.clear();
22
23    	verify(mockedList).add("first-element");
24    	verify(mockedList).add("second-element");
25    	verify(mockedList, VerificationModeFactory.times(2)).add("third-element");
26
27    	verify(mockedList).clear();
28    }
29
30}

Mockito Stub 混凝土类

使用 when() - 然后Return() 函数,我们可以建立一个混凝土 / 实现类和一个集合的单个元素。

 1package com.journaldev.mockito;
 2
 3import static org.mockito.Mockito.mock;
 4import static org.mockito.Mockito.when;
 5
 6import java.util.ArrayList;
 7
 8import org.junit.jupiter.api.Test;
 9import static org.junit.jupiter.api.Assertions.assertEquals;
10
11public class MockSingleElementTest {
12    @SuppressWarnings("unchecked")
13    @Test
14    public void testMethod() {
15    	ArrayList mockedList = mock(ArrayList.class);
16
17    	when(mockedList.get(0)).thenReturn("first-element");
18
19    	System.out.println(mockedList.get(0));
20    	assertEquals("first-element", mockedList.get(0));
21    	
22    	// "null" gets printed as get(1) is not stubbed
23    	System.out.println(mockedList.get(1));
24    }
25
26}

马克思间谍

当您调用间谍对象的方法时,将调用真实的方法,除非已定义了预先定义的行为。

 1package com.journaldev.mockito;
 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 MockitoSpyTest {
13
14    @Test
15    public void testMethod() {
16    	List<String> list = new ArrayList<>();
17    	List<String> listSpy = spy(list);
18
19    	listSpy.add("first-element");
20    	System.out.println(listSpy.get(0));
21
22    	assertEquals("first-element", listSpy.get(0));
23    	when(listSpy.get(0)).thenReturn("second-element");
24    	System.out.println(listSpy.get(0));
25    	assertEquals("second-element", listSpy.get(0));
26    }
27
28}

结论

Mockito 是用于 Java 单元测试的流行的模仿框架,我们可以使用 Mockito 轻松地模仿依赖性。Mockito 编码风格流畅,类似于 JUnit 和 TestNG 框架,因此其学习曲线非常小。

您可以从我们的 GitHub 存储库下载完整的项目代码。

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