SpringBootTest中属性转布尔值触发UnsatisfiedDependencyException求助
问题核心
在使用@SpringBootTest测试Resilience4j断路器时,因无法修改的第三方XML配置文件(securedClientContext.xml)中存在${boolean.property:true}占位符,Spring测试上下文未正确解析该占位符,导致字符串无法转换为布尔类型,抛出UnsatisfiedDependencyException。
解决方案
1. 显式设置属性值,让Spring正确解析占位符
直接在测试类中通过@SpringBootTest的properties属性指定该布尔属性值,覆盖默认占位符:
@SpringBootTest(classes = Application.class, properties = {"boolean.property=true"}) class CircuitBreakerTest { // 原有测试代码 }
也可以通过@TestPropertySource加载测试专用配置文件:
@SpringBootTest(classes = Application.class) @TestPropertySource(locations = "classpath:test-circuit-breaker.properties") class CircuitBreakerTest { // 原有测试代码 }
在test-circuit-breaker.properties中添加:
boolean.property=true
注:如果之前尝试此方法无效,检查是否有其他配置类的属性优先级更高(如环境变量、系统属性等)。
2. Mock掉出问题的第三方Bean
直接使用@MockBean注解Mock目标Bean,Spring会自动替换原有的Bean实例,避免触发原Bean的实例化逻辑:
@SpringBootTest(classes = Application.class) @MockBean(BeanIDontControlBean.class) class CircuitBreakerTest { @MockBean private Webservice webservice; private final Handler handler = new Handler(); // 原有测试方法 }
3. 排除整个Security配置类
如果该Security包下的所有Bean都与断路器测试无关,可以直接排除对应的配置类:
@SpringBootTest(classes = Application.class) @EnableAutoConfiguration(exclude = {OutboundSecurityConfiguration.class}) class CircuitBreakerTest { // 原有测试代码 }
4. 自定义测试配置覆盖第三方Bean
若需要保留Security配置的其他部分,仅替换出问题的Bean,可编写@TestConfiguration注册Mock实例:
@TestConfiguration class TestSecurityOverrideConfig { @Bean public BeanIDontControlBean beanIDontControl() { return Mockito.mock(BeanIDontControlBean.class); } } @SpringBootTest(classes = {Application.class, TestSecurityOverrideConfig.class}) class CircuitBreakerTest { // 原有测试代码 }
测试配置的Bean优先级高于XML中定义的Bean,会自动覆盖。
5. 排除指定包的组件扫描
通过自定义组件扫描规则,排除application.foundation.security包下的所有类:
@TestConfiguration @ComponentScan(basePackages = {"application.foundation", "config"}, excludeFilters = @ComponentScan.Filter( type = FilterType.REGEX, pattern = "application.foundation.security.*" )) class TestComponentScanConfig {} @SpringBootTest(classes = {Application.class, TestComponentScanConfig.class}) class CircuitBreakerTest { // 原有测试代码 }
优先级建议
优先尝试方案1(直接设置属性),若属性无法覆盖或仍有问题,使用方案2(Mock单个Bean);如果整个Security模块都不需要,则用方案3或方案5排除;需要部分保留时用方案4。
内容的提问来源于stack exchange,提问作者terrabl

