什么是 Mockito,为什么需要它?
Mockito 是一个强大的 Java 库,用于在单元测试中创建 mock 对象(桩)。它允许将测试代码与其依赖项(如数据库、外部 API、文件系统或其他服务)隔离开来。您无需使用可能速度慢、不稳定或需要复杂配置的真实对象,而是创建具有预定义行为的模拟对象。
Mockito 的主要目标是使单元测试快速、可预测且独立于外部环境。该库在 Java 生态系统(Spring、Java EE、Android)中广泛使用,是模拟事实上的标准。
关键功能:
- 创建 mock 对象 — 模拟任何类或接口。
- 定义行为 — 设置返回值、抛出异常。
- 验证调用 — 检查方法是否以特定参数被调用了指定次数。
- Spy(部分模拟) — 能够使用真实对象,但覆盖个别方法。
- 参数捕获器(ArgumentCaptor) — 提取传递给 mock 方法的参数,以便进一步验证。
安装 Mockito
由于 Mockito 是一个 Java 库,它不能通过 pip 或 npm 安装。要将其添加到项目中,请使用 Maven 或 Gradle 构建系统。
Maven(pom.xml)
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>5.12.0</version> <scope>test</scope></dependency>
<!-- 用于与 JUnit 5 一起使用 --><dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>5.12.0</version> <scope>test</scope></dependency>Gradle(build.gradle)
testImplementation 'org.mockito:mockito-core:5.12.0'testImplementation 'org.mockito:mockito-junit-jupiter:5.12.0'建议使用编写测试时最新的稳定版本。
快速入门:代码示例
考虑一个简单的例子。假设我们有一个类 UserService,它依赖于 UserRepository。我们想要测试 UserService,而无需启动数据库。
// 仓库类(依赖项)public interface UserRepository { User findById(Long id); void save(User user);}
// 服务类(待测试)public class UserService { private final UserRepository userRepository;
public UserService(UserRepository userRepository) { this.userRepository = userRepository; }
public String getUserName(Long id) { User user = userRepository.findById(id); return user != null ? user.getName() : "Unknown"; }}
// 使用 Mockito 的测试import org.junit.jupiter.api.Test;import org.junit.jupiter.api.extension.ExtendWith;import org.mockito.Mock;import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(MockitoExtension.class)public class UserServiceTest {
@Mock private UserRepository userRepository;
@Test public void testGetUserName() { // 创建 UserRepository 的 mock 对象(也可以通过 @Mock 注解) // UserRepository mockRepo = mock(UserRepository.class);
// 设置行为:当调用 findById(1L) 时返回用户 User mockUser = new User(1L, "Alice"); when(userRepository.findById(1L)).thenReturn(mockUser);