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

相关推荐
JustHappy15 分钟前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本22 分钟前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
逍遥德2 小时前
MQTT教程详解-04.SpringBoot集成MQTT(告别手动控制)
java·spring boot·物联网·中间件·iot·iotdb
IT_陈寒4 小时前
Python闭包里藏的这个坑,差点让我加班到凌晨
前端·人工智能·后端
IT_陈寒4 小时前
Java注解空指针?这个坑我踩得莫名其妙
前端·人工智能·后端
土狗TuGou5 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
ZengLiangYi5 小时前
React Query + REST API 最佳实践
javascript·后端·react.js
星浩AI5 小时前
项目实战:合同智能审批 · LangGraph + HITL 人机协同方案 [有源码]
后端·langchain·agent
JavaGuide5 小时前
Codex 接入第三方模型 DeepSeek、GLM、Kimi 教程:CC-Switch 和 Codex++ 两种方案对比
后端·ai编程
ZengLiangYi5 小时前
Fastify 加 Electron:把 Web 服务嵌进桌面应用
前端·javascript·后端