Spring Boot测试:如何断言启动的Spring应用上下文总数?
验证Spring Boot测试应用上下文总数的方案
核心思路
Spring Test的DefaultContextCache负责管理测试应用上下文缓存,但它属于包私有类无法直接获取。我们可以通过两种方式实现断言:一是统计上下文的创建次数,二是通过反射读取缓存的实际大小。
方案1:统计上下文创建次数
通过自定义ApplicationContextInitializer,在每次上下文初始化时计数,最后在全局测试类中验证总数:
1. 创建计数初始化器
import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; public class ContextCountInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { private static int contextCreateCount = 0; @Override public void initialize(ConfigurableApplicationContext applicationContext) { contextCreateCount++; } public static int getContextCreateCount() { return contextCreateCount; } public static void resetCount() { contextCreateCount = 0; } }
2. 注册初始化器
在你的抽象测试基类上添加初始化器配置,确保所有集成测试都会触发计数:
@SpringBootTest @ContextConfiguration(initializers = ContextCountInitializer.class) abstract class AbstractIntegrationTest { // 基类原有内容 }
3. 全局验证测试类
创建一个测试类,在所有测试执行完成后断言计数是否符合预期:
import org.junit.jupiter.api.AfterAll; import static org.junit.jupiter.api.Assertions.assertEquals; class ContextCreationValidationTest { @AfterAll static void validateContextCreationCount() { // 替换为你预期的上下文创建数量,比如2 assertEquals(2, ContextCountInitializer.getContextCreateCount(), "意外创建了过多的应用上下文"); // 重置计数,避免影响后续测试套件 ContextCountInitializer.resetCount(); } }
方案2:读取上下文缓存实际大小
如果需要和日志中的size值对应(即缓存中现存的上下文数量,排除被驱逐的),可以通过反射获取DefaultContextCache实例:
1. 编写缓存工具类
import org.springframework.test.context.cache.DefaultContextCache; import org.springframework.test.context.support.DefaultTestContextBootstrapper; import java.lang.reflect.Field; public class ContextCacheHelper { public static int getCachedContextSize() throws Exception { // 通过反射获取DefaultTestContextBootstrapper中的静态缓存实例 Field cacheField = DefaultTestContextBootstrapper.class.getDeclaredField("contextCache"); cacheField.setAccessible(true); DefaultContextCache cache = (DefaultContextCache) cacheField.get(null); // 返回缓存当前的大小 return cache.size(); } }
2. 全局验证测试类
import org.junit.jupiter.api.AfterAll; import static org.junit.jupiter.api.Assertions.assertEquals; class ContextCacheSizeValidationTest { @AfterAll static void validateContextCacheSize() throws Exception { // 替换为你预期的缓存大小,比如2 assertEquals(2, ContextCacheHelper.getCachedContextSize(), "上下文缓存大小超出预期"); } }
注意事项
- 方案1统计的是上下文创建次数,如果缓存达到上限触发驱逐,计数会比实际缓存的数量多;方案2直接读取缓存现存的上下文数量,和日志中的
size值一致。 - 全局验证测试类需要确保在所有其他测试执行完毕后运行,JUnit 5中可以通过
@Order(Ordered.HIGHEST_PRECEDENCE)或配置测试套件执行顺序来保证。 - 若使用Maven Surefire插件,需确保验证测试类被包含在执行范围内。
内容的提问来源于stack exchange,提问作者Vasyl Sarzhynskyi
相关产品推荐
相关产品推荐

