Mockito 是一款用于 Java 单元测试的开源模拟(Mock)框架,它允许开发者创建模拟对象(假对象)来模拟真实依赖的行为。通过用模拟对象替换真实对象,Mockito 可以让代码在隔离环境中进行测试,无需调用真实的数据库、第三方接口或外部服务,是 Spring Boot 项目单元测试的标配工具。
测试提速:规避数据库、网络请求等耗时操作,单元测试毫秒级执行
代码简洁:通过 @Mock、@InjectMocks 等注解消除样板代码
隔离测试:只测试目标业务逻辑,不受外部依赖影响
行为验证:精准校验方法是否被调用、调用次数、调用参数
无缝整合:完美兼容 JUnit 5、Spring Boot,开箱即用
模拟对象是真实对象的伪实现,专门用于测试场景。 作用:替换测试类的外部依赖(如 Service 依赖的 Mapper/Repository),让测试类独立运行。
为模拟对象的方法预设返回值或抛出异常,定义方法的执行结果。
// 示例:调用findById(1)时,直接返回预设的用户对象
when(userRepository.findById(1)).thenReturn(user);校验测试过程中,模拟对象的方法是否被调用、调用次数、调用顺序,验证代码逻辑是否正确执行。
// 验证save方法被调用1次
verify(userRepository).save(user);Mockito 提供两类核心方法:桩实现(预设结果)、行为验证(校验调用)
灵活匹配方法参数,无需固定值:
any():匹配任意对象
anyInt()/anyLong():匹配任意数字
anyString():匹配任意字符串
isNull():匹配 null
eq(值):精确匹配指定值
// 匹配任意ID,返回固定用户
when(userRepository.findById(anyInt())).thenReturn(user);Spring Boot 2.2+ 已自动集成 Mockito,无需手动添加依赖,仅需引入测试 starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency><!-- JUnit 5 核心依赖 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito 核心 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito + JUnit 5 整合 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>测试 UserService 的业务逻辑,模拟 UserRepository(数据库层),不连接真实数据库。
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String name;
}import java.util.Optional;
public interface UserRepository {
Optional<User> findById(Integer id);
User save(User user);
}import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
// 根据ID查询用户
public User getUserById(Integer id) {
return userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在"));
}
// 新增用户
public User addUser(User user) {
return userRepository.save(user);
}
}import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.*;
// 启用Mockito
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
// 1. 创建模拟对象(假的Repository)
@Mock
private UserRepository userRepository;
// 2. 注入模拟对象,创建测试目标实例
@InjectMocks
private UserService userService;
// 测试:查询用户成功
@Test
void testGetUserById_Success() {
// 预设mock行为
User mockUser = new User(1, "张三");
when(userRepository.findById(anyInt())).thenReturn(java.util.Optional.of(mockUser));
// 执行测试方法
User result = userService.getUserById(1);
// 断言结果
Assertions.assertEquals("张三", result.getName());
// 验证方法调用
verify(userRepository, times(1)).findById(1);
}
// 测试:用户不存在,抛出异常
@Test
void testGetUserById_NotFound() {
// 预设返回空
when(userRepository.findById(anyInt())).thenReturn(java.util.Optional.empty());
// 断言抛出异常
RuntimeException exception = Assertions.assertThrows(RuntimeException.class,
() -> userService.getUserById(1));
Assertions.assertEquals("用户不存在", exception.getMessage());
}
}@Mock:完全模拟,所有方法默认不执行真实逻辑,必须手动桩实现
@Spy:部分模拟,默认执行真实方法,可自定义部分方法
@Spy
private UserService userService;
// Spy 桩实现写法
doReturn(new User(1,"测试")).when(userService).getUserById(1);更符合人类思维的测试写法:given(预设)→ when(执行)→ then(断言)
import static org.mockito.BDDMockito.given;
@Test
void testBDD() {
// given 预设
User mockUser = new User(1, "张三");
given(userRepository.findById(1)).willReturn(java.util.Optional.of(mockUser));
// when 执行
User result = userService.getUserById(1);
// then 断言
Assertions.assertEquals("张三", result.getName());
}Mockito 原生不支持静态 / 私有方法 mock,需整合 PowerMock(企业常用)。
只测试业务逻辑:Service 层是单元测试核心,Controller/Mapper 无需 Mockito 测试
隔离依赖:所有外部依赖(数据库、Redis、第三方接口)全部用 Mock 替代
全覆盖场景:正常场景 + 异常场景 + 边界场景都要编写测试用例
不连接真实环境:单元测试必须独立运行,不依赖数据库 / 网络
行为验证:不仅校验返回值,还要校验依赖方法是否正确调用
核心定位:Mockito 是 Java 单元测试的模拟框架,用于隔离外部依赖
核心注解:@Mock(创建假对象)、@InjectMocks(注入依赖)、@ExtendWith(启用框架)
核心操作:when().thenReturn()(预设结果)、verify()(验证调用)
核心价值:让单元测试独立、快速、稳定,是保障代码质量的核心工具
Spring Boot 整合:开箱即用,无需额外配置,是企业级项目标配