Spring集成测试:上下文缓存复用问题及实现方法
问题描述
我为所有集成测试编写了如下基类:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) @ContextConfiguration(classes = {Config1.class, Config2.class}) @TestPropertySource(properties = { "zonky.test.database.postgres.docker.image=my-image", "spring.profiles.active=test" }) @AutoConfigureEmbeddedDatabase public abstract class IntegrationTestBaseConfiguration { }
每个具体测试类的写法如下:
@ContextConfiguration(classes = {Config3.class}) class ConcreteIntegrationTest extends IntegrationTestBaseConfiguration { //tests }
请问:IntegrationTestBaseConfiguration中定义的上下文是否会在所有集成测试中复用共享?若不能,该如何实现上下文复用?
回答
当前情况无法复用上下文
你现在的写法不能实现上下文复用。原因是每个具体测试类上的@ContextConfiguration(classes = {Config3.class})会直接覆盖基类的@ContextConfiguration配置,导致每个测试类的上下文配置集合不一致。Spring测试框架会根据上下文配置的哈希值来缓存上下文,只要配置有差异,就会创建新的上下文实例。
实现上下文复用的方案
1. 避免覆盖上下文配置,改用@Import导入额外配置
不要在具体测试类上添加@ContextConfiguration,如果需要引入额外的配置类,使用@Import注解来追加配置,而不是覆盖:
@Import(Config3.class) class ConcreteIntegrationTest extends IntegrationTestBaseConfiguration { // tests }
这样基类的Config1、Config2会被继承,同时导入Config3,所有测试类的上下文配置保持一致(只要导入的额外配置不冲突或差异化),Spring就会复用同一个上下文。
2. 确保所有测试类的配置完全一致
Spring上下文缓存的核心判断依据是配置的唯一性,需要保证所有测试类的以下内容完全相同:
- 导入的配置类集合
@TestPropertySource指定的属性- 激活的Spring Profile
@SpringBootTest的配置参数- 其他影响上下文初始化的注解配置
只要有任意一项不同,Spring就会创建新的上下文。
3. 保持基类注解的继承性
基类上的@SpringBootTest、@TestPropertySource等注解已经会被子类继承,不要在子类中重复添加或修改这些注解的参数,避免破坏配置的一致性。
内容的提问来源于stack exchange,提问作者flywell
相关产品推荐
相关产品推荐

