原文: https://howtodoinjava.com/mockito/junit-mockito-example/
在本 mockito 教程中,学习了 Mockito 框架的基础知识,如何编写 junit 测试以及模拟,样例设置和带有示例的注解。
Table of Contents
1\. Introduction
2\. Setting Up
3\. Annotations
4\. Example
1. Mockito 简介
在应用的单元测试期间,有时无法复制精确的生产环境。 有时数据库不可用,有时不允许网络访问。 可以有更多这样的限制。 为了解决这些限制,我们必须为这些不可用的资源创建模拟。
Mockito 是一个开放源代码框架,可让您轻松创建测试双打(模拟)。 对于您出于测试目的而替换生产对象的任何情况,双重测试是一个通用术语。
在模拟中,我们通常使用以下类型的测试双打。
- 存根 – 是一个对象,该对象对测试期间执行的方法执行具有预定义的返回值。
- 间谍 – 与存根相似的对象,但它们另外记录了它们的执行方式。
- 模拟 – 是在测试期间对方法执行返回值并记录了对这些执行的期望的对象。 如果模拟人收到了他们不期望的电话,并且在验证过程中对其进行了检查,以确保他们收到了所有期望的电话,它们可能会引发异常。
我们可以在测试类中模拟接口和类。 Mockito 还可以在使用 Mockito 注解时帮助产生最少的样板代码。
2. Mockito 设置
要将 Mockito 添加到项目中,我们可以通过任何方式添加所需的 Mockito 版本,即 maven ,gradle 或 jar 文件。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
下面给出了具有创建 Junit 测试以及 mockito 的所有依赖项的完整 pom 文件。 否则,我们需要查找并添加objenesis
,hamcrest-core
,byte-buddy
,byte-buddy-agent
,junit
和mockito
的匹配版本。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.howtodoinjava.demo</groupId>
<artifactId>MockitoExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. Mockito 注解
在敲键盘来编写应用和单元测试之前,让我们快速概述有用的 Mockito 注解。
@Mock
用于模拟创建。 它使测试类更具可读性。@Spy
用于创建间谍实例。 我们可以使用它代替spy(Object)
方法。@InjectMock
用于自动实例化测试对象,并将所有@Mock
或@Spy
带注解的字段依赖项注入其中(如果适用)。@Captor
用于创建参数捕获器
阅读更多:
@Mock
和@InitMock
注解之间的区别
要处理所有上述注解,MockitoAnnotations.initMock(testClass);
必须至少使用一次。 要处理注解,我们可以使用内置运行器MockitoJUnitRunner
或规则MockitoRule
。 我们还可以在@Before
带注解的 Junit 方法中显式调用initMock()
方法。
//1
@RunWith(MockitoJUnitRunner.class)
public class ApplicationTest {
//code
}
//2
public class ApplicationTest {
@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_Stub);
//code
}
//3
public class ApplicationTest {
@Before
public void init() {
MockitoAnnotations.initMock(this);
}
}
4. JUnit Mockito 示例
让我们学习编写将模拟程序用于依赖项的 junit 测试。 给定的示例具有RecordService
,该文件在DatabaseDAO
和NetworkDAO
的帮助下将给定文件存储在数据库和网络位置中。
在测试环境中,无法访问数据库或网络位置,因此我们正在为两个仓库创建模拟。
public class DatabaseDAO
{
public void save(String fileName) {
System.out.println("Saved in database");
}
}
public class NetworkDAO
{
public void save(String fileName) {
System.out.println("Saved in network location");
}
}
public class RecordService
{
DatabaseDAO database;
NetworkDAO network;
//setters and getters
public boolean save(String fileName)
{
database.save(fileName);
System.out.println("Saved in database in Main class");
network.save(fileName);
System.out.println("Saved in network in Main class");
return true;
}
}
请记住,如果我们使用诸如 Spring 之类的任何 DI 框架,那么我们可能已经使用了注解@Autowired
。
要测试这个RecordService
类,让我们创建一个单元测试。
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMock;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import com.howtodoinjava.demo.mockito.DatabaseDAO;
import com.howtodoinjava.demo.mockito.NetworkDAO;
import com.howtodoinjava.demo.mockito.RecordService;
@RunWith(MockitoJUnitRunner.class)
public class ApplicationTest
{
@InjectMock
RecordService recordService;
@Mock
DatabaseDAO databaseMock;
@Mock
NetworkDAO networkMock;
@Test
public void saveTest()
{
boolean saved = recordService.save("temp.txt");
assertEquals(true, saved);
verify(databaseMock, times(1)).save("temp.txt");
verify(networkMock, times(1)).save("temp.txt");
}
}
让我们逐步了解以上测试类:
- 用
@RunWith(MockitoJUnitRunner.class)
注解测试,以便 Mockito 可以处理注解。 - 使用
@Mock
注解对 dao 字段进行注解,以为它们两个实例化一个模拟对象。 - 使用
@InjectMock
注解对服务字段进行注解,以首先实例化然后注入两个模拟的依赖项。 - 在要测试的类上调用方法进行测试,即
recordService
。 - 验证模拟对象中的方法已被调用。
还有许多其他方法可以测试方法和模拟的依赖项,我们将在以后的文章中介绍。
将有关此 junit Mockito2 示例的问题交给我。
学习愉快!