# Mockito2 教程 – JUnit Mockito 示例

> 原文： [https://howtodoinjava.com/mockito/junit-mockito-example/](https://howtodoinjava.com/mockito/junit-mockito-example/)

在本 **mockito 教程**中，学习了 Mockito 框架的基础知识，如何编写 [junit](https://howtodoinjava.com/junit-4/) 测试以及模拟，样例设置和带有示例的注解。

```java
Table of Contents

1\. Introduction
2\. Setting Up
3\. Annotations
4\. Example
```

## 1\. Mockito 简介

在应用的单元测试期间，有时无法复制精确的生产环境。 有时数据库不可用，有时不允许网络访问。 可以有更多这样的限制。 为了解决这些限制，我们必须为这些不可用的资源创建模拟。

Mockito 是一个开放源代码框架，可让您轻松创建[测试双打](https://www.martinfowler.com/bliki/TestDouble.html)（模拟）。 对于您出于测试目的而替换生产对象的任何情况，双重测试是一个通用术语。

在模拟中，我们通常使用以下类型的测试双打。

*   **存根** – 是一个对象，该对象对测试期间执行的方法执行具有预定义的返回值。
*   **间谍** – 与存根相似的对象，但它们另外记录了它们的执行方式。
*   **模拟** – 是在测试期间对方法执行返回值并记录了对这些执行的期望的对象。 如果模拟人收到了他们不期望的电话，并且在验证过程中对其进行了检查，以确保他们收到了所有期望的电话，它们可能会引发异常。

我们可以在测试类中模拟接口和类。 Mockito 还可以在使用 Mockito 注解时帮助产生最少的样板代码。

## 2\. Mockito 设置

要将 Mockito 添加到项目中，我们可以通过任何方式添加所需的 Mockito 版本，即 [maven](https://mvnrepository.com/artifact/org.mockito/mockito-core) ，gradle 或 [jar 文件](http://central.maven.org/maven2/org/mockito/mockito-core/2.23.4/mockito-core-2.23.4.jar)。

```java
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

```

```java
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'

```

下面给出了具有创建 Junit 测试以及 mockito 的所有依赖项的完整 pom 文件。 否则，我们需要查找并添加`objenesis`，`hamcrest-core`，`byte-buddy`，`byte-buddy-agent`，`junit`和`mockito`的匹配版本。

```java
<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`注解之间的区别](https://howtodoinjava.com/mockito/mockito-mock-initMock/)

要处理所有上述注解，`MockitoAnnotations.initMock(testClass);`必须至少使用一次。 要处理注解，我们可以使用内置运行器`MockitoJUnitRunner`或规则`MockitoRule`。 我们还可以在`@Before`带注解的 Junit 方法中显式调用`initMock()`方法。

```java
//1

@RunWith(MockitoJUnitRunner.class)
public class ApplicationTest {
	//code
}

```


```java
//2

public class ApplicationTest {
	@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_Stub);

	//code
}

```

```java
//3

public class ApplicationTest {
	@Before
	public void init() {
		MockitoAnnotations.initMock(this);
	}
}

```

## 4\. JUnit Mockito 示例

让我们学习编写将模拟程序用于依赖项的 junit 测试。 给定的示例具有`RecordService`，该文件在`DatabaseDAO`和`NetworkDAO`的帮助下将给定文件存储在数据库和网络位置中。

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

```java
public class DatabaseDAO 
{
	public void save(String fileName) {
		System.out.println("Saved in database");
	}
}

```

```java
public class NetworkDAO 
{
	public void save(String fileName) {
		System.out.println("Saved in network location");
	}
}

```

```java
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`类，让我们创建一个单元测试。

```java
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 文档](https://static.javadoc.io/org.mockito/mockito-core/2.9.0/org/mockito/Mockito.html)