Java测试中Mockito的使用 | AI生成和翻译

Home 2025.02

在 Java 测试中使用 Mockito 时,请按照以下步骤创建模拟对象、桩方法及验证交互:

1. 添加依赖

pom.xml (Maven) 中包含 Mockito 和 JUnit:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.3.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>

2. 设置测试类

结合 JUnit 5 使用 Mockito 扩展:

import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
    // ...
}

3. 创建模拟对象并注入依赖

@Mock
private UserRepository userRepository;

@InjectMocks
private UserService userService; // UserService 依赖 UserRepository

4. 桩方法调用

使用 when().thenReturn() 定义模拟行为:

@Test
void getUserById_ReturnsUser_WhenUserExists() {
    User mockUser = new User(1L, "Alice");
    // 对仓库方法进行桩设置
    when(userRepository.findById(1L)).thenReturn(mockUser);

    User result = userService.getUserById(1L);
    
    assertEquals("Alice", result.getName());
}

5. 验证交互

检查模拟方法是否按预期被调用:

@Test
void getUserById_CallsRepository() {
    userService.getUserById(1L);
    // 验证仓库方法被调用一次且参数为 ID 1
    verify(userRepository, times(1)).findById(1L);
}

常见使用场景

桩异常抛出

@Test
void getUserById_ThrowsException_WhenRepositoryFails() {
    when(userRepository.findById(anyLong())).thenThrow(new RuntimeException("数据库错误"));
    
    assertThrows(RuntimeException.class, () -> userService.getUserById(1L));
}

参数匹配器

使用 any(), eq() 等实现灵活参数匹配:

when(userRepository.findById(anyLong())).thenReturn(new User(1L, "Bob"));

BDD(行为驱动开发)风格

使用 given().willReturn() 提升可读性:

import static org.mockito.BDDMockito.*;

@Test
void bddStyleExample() {
    given(userRepository.findById(1L)).willReturn(new User(1L, "Alice"));
    
    User result = userService.getUserById(1L);
    
    then(userRepository).should().findById(1L);
    assertEquals("Alice", result.getName());
}

参数捕获器

捕获参数以执行详细断言:

@Test
void saveUser_CapturesArgument() {
    ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
    
    userService.saveUser("Charlie");
    
    verify(userRepository).save(userCaptor.capture());
    assertEquals("Charlie", userCaptor.getValue().getName());
}

关键要点

故障排除

进阶用法请参阅 Mockito 官方文档


Back Donate