如何在ApplicationContextRunner中应用AutoConfigurationDisablingFilter以测试自动配置禁用逻辑
我完全理解你遇到的痛点——用ApplicationContextRunner测试自定义自动配置时,要么自定义的AutoConfigurationDisablingFilter不生效,要么找不到合适的方式把它嵌入测试流程里。其实核心问题出在你当前的测试写法绕过了Spring Boot自动配置的过滤环节,咱们一步步来解决:
为什么你的代码不生效?
你用AutoConfigurations.of(...)直接指定了要加载的自动配置类(包括那个本该被禁用的BuiltInAutoConfigurationThatShouldBeDisabled),这种方式会直接导入这些类,完全跳过了AutoConfigurationImportFilter的过滤逻辑。而且ApplicationContextRunner默认不会自动扫描META-INF/spring.factories里的过滤器(除非你触发完整的自动配置流程)。
解决方案:用@ImportAutoConfiguration显式触发过滤逻辑
最稳妥的方式是通过测试配置类,结合@ImportAutoConfiguration的filters属性,让过滤器在自动配置导入阶段生效。具体步骤如下:
1. 编写内部测试配置类
创建一个测试专用的配置类,用@ImportAutoConfiguration指定要参与测试的自动配置类和要应用的过滤器:
@ImportAutoConfiguration( // 列出所有要测试的自动配置类(包括目标禁用的那个) classes = {MyCustomAutoConfiguration.class, BuiltInAutoConfigurationThatShouldBeDisabled.class}, // 指定你的自定义禁用过滤器 filters = MyAutoConfigurationDisablingFilter.class ) static class TestAutoConfig { }
2. 调整ApplicationContextRunner测试代码
用withUserConfiguration导入上面的测试配置类,这样就能完整触发过滤器的逻辑:
new ApplicationContextRunner() .withUserConfiguration(TestAutoConfig.class) .run(context -> { // 验证被禁用的配置类对应的Bean确实没有被创建 assertThat(context).doesNotHaveBean(SomeBeanInDisabledConfiguration.class); });
备选方案:依赖spring.factories+完整自动配置
如果你已经在META-INF/spring.factories里注册了过滤器(比如org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=com.example.MyAutoConfigurationDisablingFilter),也可以通过启用完整自动配置流程让它生效:
new ApplicationContextRunner() // 启用自动配置,触发Spring Boot的过滤器加载逻辑 .withConfiguration(AutoConfigurations.of(MyCustomAutoConfiguration.class)) // 确保要禁用的配置类在classpath中会被自动发现 .run(context -> { assertThat(context).doesNotHaveBean(SomeBeanInDisabledConfiguration.class); });
这种方式适合模拟真实环境下的自动配置行为,但要注意确保目标禁用的配置类会被Spring Boot自动扫描到。
关键注意点
- 你的
MyAutoConfigurationDisablingFilter必须正确实现org.springframework.boot.autoconfigure.AutoConfigurationImportFilter接口,并且match方法逻辑要准确(返回false表示要过滤掉对应的自动配置类)。 - 绝对不要用
AutoConfigurations.of(...)直接包含本该被禁用的配置类,否则会完全绕过过滤逻辑。
备注:内容来源于stack exchange,提问作者Mauro Molinari

