Mockito2 教程 – JUnit Mockito 示例

Mockito2 教程 – JUnit Mockito 示例

原文: 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 文件。 否则,我们需要查找并添加objenesishamcrest-corebyte-buddybyte-buddy-agentjunitmockito的匹配版本。

<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,该文件在DatabaseDAONetworkDAO的帮助下将给定文件存储在数据库和网络位置中。

在测试环境中,无法访问数据库或网络位置,因此我们正在为两个仓库创建模拟。

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 示例的问题交给我。

学习愉快!

参考: Mockito Core Java 文档