Spring Boot 测试最佳实践

🧪 1. 测试分层策略 (Testing Strategy / Pyramid)

核心思想:多写单元测试,少写E2E测试
Core idea: More unit tests, fewer E2E tests

复制代码
        E2E Tests(少 / Few)
     Integration Tests(中 / Medium)
Unit Tests(多 / Many)

✅ 2. 单元测试最佳实践 (Unit Testing Best Practices)

👉 使用:JUnit + Mockito

✔ 原则 / Principles

  • 只测试一个类 (Test one class only)

  • Mock 外部依赖 (Mock dependencies)

  • 不连接数据库/网络 (No DB / network)


✔ 示例 / Example

复制代码
@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    void shouldReturnUser_whenUserExists() {
        User user = new User(1L, "Neo");

        when(userRepository.findById(1L)).thenReturn(Optional.of(user));

        User result = userService.getUserById(1L);

        assertEquals("Neo", result.getName());
    }
}

💡 关键点 / Key Points

  • 使用 @Mock 模拟依赖

  • 使用 @InjectMocks 注入被测类

  • Use @Mock to isolate dependencies

  • Use @InjectMocks for target class


🔗 3. 集成测试最佳实践 (Integration Testing)

👉 使用:@SpringBootTest


✔ 原则 / Principles

  • 测试模块之间真实交互 (Test real interactions)

  • 可以连接数据库 (DB allowed)

  • 使用测试数据库 (Use test DB, e.g. H2)


✔ 示例 / Example

复制代码
@SpringBootTest
@Transactional
class UserServiceIntegrationTest {

    @Autowired
    private UserService userService;

    @Test
    void shouldSaveUser() {
        User user = new User(null, "Neo");

        User saved = userService.save(user);

        assertNotNull(saved.getId());
    }
}

💡 建议 / Tips

  • 使用 H2 内存数据库 (Use H2 in-memory DB)

  • 使用 @Transactional 自动回滚

  • Rollback after each test


🌐 4. Controller / API 测试 (Web Layer Testing)

👉 使用:@WebMvcTest + MockMvc


✔ 示例 / Example

复制代码
@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void shouldReturnUser() throws Exception {
        when(userService.getUserById(1L))
            .thenReturn(new User(1L, "Neo"));

        mockMvc.perform(get("/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("Neo"));
    }
}

💡 关键点 / Key Points

  • 只加载 Web 层 (Load only web layer)

  • 使用 @MockBean 替代真实 Service

  • Use MockMvc to simulate HTTP calls


🧩 5. 数据库测试 (Repository Testing)

👉 使用:@DataJpaTest


✔ 示例 / Example

复制代码
@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void shouldFindByName() {
        userRepository.save(new User(null, "Neo"));

        Optional<User> user = userRepository.findByName("Neo");

        assertTrue(user.isPresent());
    }
}

💡 特点 / Features

  • 只加载 JPA 相关组件

  • Faster than full Spring context

  • 默认使用内存数据库


🔁 6. 回归测试策略 (Regression Strategy)

✔ 建议 / Recommendations

  • 每次提交运行单元测试

    Run unit tests on every commit

  • CI/CD 运行全部测试

    Run all tests in pipeline

  • 关键路径加 E2E

    Add E2E for critical flows


🚀 7. 测试命名规范 (Naming Convention)

👉 推荐格式 / Recommended format:

复制代码
should + ExpectedResult + when + Condition

示例 / Example

  • shouldReturnUser_whenUserExists

  • shouldThrowException_whenUserNotFound


⚠️ 8. 常见错误 (Common Mistakes)

❌ 写太多集成测试 → 慢

Too many integration tests → slow

❌ 单元测试依赖数据库

Unit test depends on DB

❌ 不做Mock

No mocking → not isolated

❌ 测试没有断言

No assertions


🧠 9. 最佳实践总结 (Final Summary)

类型 工具 用途
单元测试 JUnit + Mockito 快速、隔离
集成测试 @SpringBootTest 模块协作
Web测试 @WebMvcTest API层
数据库测试 @DataJpaTest JPA

💡 一句话总结 (One-line takeaway)

👉 80% 单元测试 + 15% 集成测试 + 5% E2E

👉 Focus on unit tests, use integration wisely

相关推荐
计算机安禾5 分钟前
【c++面向对象编程】第9篇:友元(friend):破坏封装的“特权”——真的有害吗?
java·c++·log4j
铭毅天下10 分钟前
当搜索引擎遇上 Rust——深度解读下一代实时搜索引擎 INFINI Pizza
开发语言·后端·搜索引擎·rust
用户2986985301410 分钟前
Java 后端处理 Word 修订:批量接受与拒绝的自动化方案
java·后端
马艳泽17 分钟前
win11环境查找jar包中字符串
后端
宁&沉沦23 分钟前
后端各框架热启动 极简启动命令(直接复制用)
后端
枕星而眠23 分钟前
Linux 共享内存与信号量全解析:原理、实践与避坑指南
linux·c语言·开发语言·后端·ubuntu
kree24 分钟前
Meilisearch:轻量搜索引擎的优雅选择,以及它在 RAG 中的应用
后端
Ting-yu32 分钟前
SpringCloud快速入门(2)---- SpringCloud简介
后端·spring·spring cloud
guchen6639 分钟前
WPF的启动机制
前端·后端
Java水解1 小时前
如何更好的创建skill
后端