10.1 — 集成测试与切片测试
定位: Spring Boot 集成测试和切片测试的使用与对比 面试高频度: ⭐⭐⭐ 考查方式: @SpringBootTest 选项、切片测试分类、@DirtiesContext
一、这是什么?为什么需要它?
@SpringBootTest 启动完整 Spring 上下文进行集成测试。切片测试只加载应用的一部分(如 Web 层或 JPA 层),启动更快、专注测试范围。
二、原理拆解
2.1 @SpringBootTest 集成测试
java
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class ApplicationIntegrationTest {
@Autowired
private UserService userService;
@Autowired
private TestRestTemplate restTemplate;
@Test
void testFullContext() {
User user = userService.findById(1L);
assertThat(user).isNotNull();
}
}WebEnvironment 选项
| 选项 | 说明 | 端口 |
|---|---|---|
| MOCK | 加载 Servlet Mock,不启动真实服务器 | — |
| RANDOM_PORT | 启动真实服务器,随机端口 | ✅ |
| DEFINED_PORT | 使用配置的端口 | ✅ |
| NONE | 不加载 Web 环境 | — |
2.2 切片测试
| 切片注解 | 加载的组件 | 用途 |
|---|---|---|
| @WebMvcTest | Controller 层 | Controller 测试,Mock Service |
| @DataJpaTest | JPA 组件 | Repository 测试 |
| @JsonTest | JSON 序列化 | JSON 格式测试 |
| @RestClientTest | REST 客户端 | RestTemplate/WebClient 测试 |
java
// @WebMvcTest 示例
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void testGetUser() throws Exception {
given(userService.findById(1L)).willReturn(new User(1L, "Alice"));
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}2.3 @DirtiesContext
在测试后重置 ApplicationContext,用于修改了容器状态的测试。
| 场景 | 说明 |
|---|---|
| 修改缓存状态 | 测试修改了缓存中的值 |
| 修改配置 | 测试修改了 Environment 属性 |
| 修改 Bean 状态 | 测试修改了单例 Bean 的内部状态 |
⚠️ 注意:@DirtiesContext 会导致 ApplicationContext 重建,非常耗时。
三、面试视角
| 追问 | 答案要点 |
|---|---|
| @SpringBootTest 和切片测试的区别? | 前者加载完整上下文(慢),后者只加载部分(快) |
| 切片测试的意义? | 专注测试范围、启动快、Mock 外部依赖 |
| @DirtiesContext 的性能影响? | 每次重建 ApplicationContext,非常耗时,尽量少用 |
📚 相关链接
- **Mock与Testcontainers** — Mock 和真实容器测试
- ← 返回 **返回 测试与质量索引**