🧪 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
@Mockto isolate dependencies -
Use
@InjectMocksfor 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
MockMvcto 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