Skip to content

10.2 — Mock 与 Testcontainers

定位: Spring 测试中的 Mock 技术和真实中间件集成 面试高频度: ⭐⭐⭐ 考查方式: @MockBean vs @SpyBean、Testcontainers 使用场景

一、这是什么?为什么需要它?

@MockBean/@SpyBean 将 Mockito Mock 注入到 ApplicationContext,替代真实 Bean。Testcontainers 在测试中使用 Docker 运行真实数据库/中间件。

二、原理拆解

2.1 @MockBean

java
@WebMvcTest(UserController.class)
class UserControllerTest {
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean  // 创建 Mock 并替换容器中的 UserService Bean
    private UserService userService;
    
    @Test
    void testCreateUser() {
        given(userService.create(any(UserCreateRequest.class)))
            .willReturn(new User(1L, "Alice"));
            
        mockMvc.perform(post("/api/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"name\":\"Alice\"}"))
            .andExpect(status().isCreated());
    }
}

2.2 @MockBean vs @SpyBean

特性@MockBean@SpyBean
默认行为所有方法返回默认值调用真实方法
需要打桩所有方法需手动定义仅需指定方法
验证真实调用需 verify默认真实调用
适用场景完全 Mock 外部依赖部分 Mock,部分真实

2.3 Testcontainers 集成

java
@Testcontainers
@SpringBootTest
class UserRepositoryTC {
    @Container
    static PostgreSQLContainer<?> postgres = 
        new PostgreSQLContainer<>("postgres:15")
        .withDatabaseName("testdb")
        .withUsername("test")
        .withPassword("test");
    
    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }
}

Testcontainers vs H2

对比项TestcontainersH2
数据库真实数据库内存数据库
SQL 兼容性100% 一致可能有差异
启动速度
适用场景CI/CD、集成测试单元测试
资源占用

推荐:单元测试用 H2,集成测试用 Testcontainers。

三、面试视角

追问答案要点
@MockBean 和 @Mock 的区别?@MockBean 将 Mock 注入到 ApplicationContext,@Mock 是普通 Mockito Mock
@MockBean 和 @SpyBean 的不同?MockBean 全部打桩,SpyBean 部分打桩+部分真实
Testcontainers 相比 H2 的优势?SQL 100% 兼容,能发现 H2 无法发现的方言问题

📚 相关链接

  • **集成测试与切片测试** — Spring Boot 测试基础
  • ← 返回 **返回 测试与质量索引**

Knowledge4J — Java 知识库