Mockito是一个流行的Java模拟框架,它允许你在单元测试中创建和配置模拟对象,以便在测试过程中替换那些不容易构造或获取的对象。
Mockito可以与JUnit无缝集成,下面的示例演示 Mockito + JUnit实现模拟对象的单元测试。
依赖导入
这里使用Maven进行依赖的管理, 在pom.xml 中需要导入JUnit 和Mockito相关的依赖。
<?xml version="1.0" encoding="UTF-8"?>
<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.osxm.test.javaut</groupId><artifactId>java-unittest</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><junit.jupiter.version>5.11.0</junit.jupiter.version><junit.platform.version>1.9.3</junit.platform.version></properties><dependencies> <!-- JUnit Jupiter API for writing tests --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>${junit.jupiter.version}</version> <scope>test</scope> </dependency> <!-- JUnit Jupiter Engine for executing tests --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>${junit.jupiter.version}</version> <scope>test</scope> </dependency> <!-- (Optional) Only required to run tests in an IDE without built-in support for JUnit 5<dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <version>${junit.platform.version}</version> <scope>test</scope> </dependency> --> <!-- Mockito核心依赖 --><dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>5.14.2</version><scope>test</scope></dependency><!-- 如果需要Mockito的JUnit集成,可以添加以下依赖 --><dependency><groupId>org.mockito</groupId><artifactId>mockito-junit-jupiter</artifactId><version>5.14.2</version><scope>test</scope></dependency></dependencies> </project>
- junit-jupiter-api : 在写测试的时候需要导入的一些JUnit 的类
- junit-jupiter-engine 运行JUnit 测试的引擎
- junit-platform-launcher 一般不需要导入,用于在不内置支持JUnit5的IDE运行
- mockito-core ,Mockito核心依赖 ,包括mockito的一些类和注解。
- mockito-junit-jupiter: Mockito与JUnit的集成
源代码
MyService
是一个服务类 ,它依赖于MyDependency
。 在MyService
的 myServiceMethod
方法中会调用 MyDependency
的 getData()
方法。
/*** Copyright (C) Oscar Chen(XM):* * Date: 2024-11-10* Author: XM*/
package com.osxm.test.mock;public class MyService {private MyDependency myDependency;// 构造函数注入依赖MyService(MyDependency myDependency) {this.myDependency = myDependency;}// 被测试的方法String myServiceMethod() {String data = myDependency.getData();return "processed " + data;}
}
/*** Copyright (C) Oscar Chen(XM):* * Date: 2024-11-10* Author: XM*/
package com.osxm.test.mock;public class MyDependency {String getData() {// 真实实现,但在测试中会被模拟return "real data";}
}
Mock 单元测试
Mock的单元测试代码如下:
/*** Copyright (C) Oscar Chen(XM):* * Date: 2024-11-10* Author: XM*/
package com.osxm.test.mock;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;public class MyServiceTest {@Mockprivate MyDependency myDependency; // 创建一个模拟对象@InjectMocksprivate MyService myService; // 创建一个被测试对象,并注入模拟对象@BeforeEachvoid setUp() {MockitoAnnotations.openMocks(this); // 初始化模拟对象}@Testvoid testMyServiceMethod() {// 设置模拟对象的行为when(myDependency.getData()).thenReturn("mocked data");// 调用被测试对象的方法String result = myService.myServiceMethod();// 验证结果assertEquals("processed mocked data", result);// 验证模拟对象的方法是否被调用verify(myDependency).getData();}
}
在测试中,
- 使用
@Mock
注解来创建MyDependency
的模拟对象, - 并使用
@InjectMocks
注解来创建MyService
的实例,同时将模拟对象注入其中。 - 然后,使用
when
和thenReturn
方法来设置模拟对象的行为 - 最后调用被测试对象的方法并验证结果和交互。
请注意,上述示例中的MockitoAnnotations.openMocks(this)
方法是在JUnit 5中初始化Mockito注解的推荐方式。如果你使用的是JUnit 4,则应使用MockitoAnnotations.initMocks(this)
方法。此外,如果使用的是@RunWith(MockitoJUnitRunner.class)
注解来运行测试,则无需手动调用初始化方法,因为MockitoJUnitRunner
会自动处理。
运行
在VS Code中运行的效果如下: