CC 咖啡猫的工作空间 Coding Space

单元测试实践

单元测试保障代码质量,是防御式编程的重要一环。


1. 测试框架对比

框架 特点 适用场景
JUnit 5 最新标准、Lambda 支持 Spring Boot 默认
TestNG 依赖测试、并发执行 复杂测试场景
Mockito Mock 框架 隔离依赖
AssertJ 流式断言 易读断言
Spring Test Spring 上下文支持 Spring 项目

2. 常用注解

@SpringBootTest
@DisplayName("用户服务测试")
class UserServiceTest {

    @MockBean
    private UserMapper userMapper;

    @Autowired
    private UserService userService;

    @Test
    @Order(1)
    @DisplayName("创建用户 - 成功")
    void createUser_success() {
        // given
        UserRequest req = new UserRequest();
        req.setUsername("test");
        req.setMobile("13800138000");
        when(userMapper.insert(any())).thenReturn(1);

        // when
        User result = userService.createUser(req);

        // then
        assertThat(result).isNotNull();
        assertThat(result.getUsername()).isEqualTo("test");
        verify(userMapper, times(1)).insert(any());
    }

    @Test
    @DisplayName("创建用户 - 用户名重复")
    void createUser_duplicateUsername() {
        // given
        when(userMapper.findByUsername("test")).thenReturn(existingUser);

        // when & then
        assertThatThrownBy(() -> userService.createUser(req))
            .isInstanceOf(BusinessException.class)
            .hasMessageContaining("用户名已存在");
    }
}

3. 测试分类

类型 说明 占比建议
单元测试 (UT) 测试单个方法,Mock 外部依赖 70%
集成测试 (IT) 测试多个组件协作,真实数据库 20%
端到端测试 (E2E) 测试完整业务流程(常用于核心业务的流程测试,不会每个接口都写E2E) 10%

4. 常用断言

// 普通断言
assertEquals(expected, actual);
assertNotNull(result);
assertTrue(list.isEmpty());
assertThat(actual).isBetween(1, 10);

// 异常断言
assertThrows(BusinessException.class, () -> service.doSomething());

// JSON 断言
assertThatJson(response)
    .hasFieldOrProperty("id")
    .extracting("name").isEqualTo("test");

// 集合断言
assertThat(users)
    .hasSize(3)
    .extracting(User::getName)
    .containsExactly("A", "B", "C");

5. 测试金字塔

           ┌─────────┐
           │   E2E   │     少量、关键路径
           ├─────────┤
           │ 集成测试 │     中等、按模块
           ├─────────┤
           │ 单元测试 │     大量、快速
           └─────────┘

6. 注意事项

  1. 测试独立:每个测试用例独立,不依赖其他测试
  2. 命名清晰方法名_场景_预期 命名规范
  3. Given-When-Then: Arrange-Act-Assert 模式
  4. 覆盖率适度:核心业务 > 70%,工具类 > 80%
  5. 避免测试私有方法:通过公开接口测试

最后更新:2026/05/13