You need to enable JavaScript to run this app. 为何@SpringBootTest测试不解析配置占位符但应用启动会报错
优惠活动
大模型
产品
解决方案
定价
更多

为何@SpringBootTest测试不解析配置占位符但应用启动会报错

问题根因

两个场景下Spring的占位符未解析处理策略不同,是差异的核心来源:

  • 正式启动的Spring Boot应用默认会加载@SpringBootApplication带来的自动配置,其中内置的PropertySourcesPlaceholderConfigurer的ignoreUnresolvablePlaceholders属性默认为false,只要检测到无法解析的${xxx}占位符就会直接抛出IllegalArgumentException,也就是你看到的启动报错。
  • 你写的单元测试仅指定了@SpringBootTest(classes = Config.class),没有加载完整的主应用自动配置链,测试场景下默认的占位符解析器会将ignoreUnresolvablePlaceholders设为true,遇到无法解析的占位符时不会抛异常,而是直接保留${val}的原始字符串内容,所以单元测试可以正常运行,返回的Map值就是原始的占位符字符串。

补充说明

你用到的@Value("#{${Measurement}}")是嵌套解析逻辑:第一步先解析${Measurement}拿到配置里的JSON字符串,第二步再把JSON作为SpEL表达式解析为Map。测试场景下第二步解析到JSON内部的${val}时,因为忽略未解析占位符的策略,不会触发错误,仅保留原始值;而正式环境会在校验阶段直接拦截到未解析的占位符,提前抛出异常。

复现正式环境报错的测试配置

如果希望单元测试和正式环境行为对齐,可以在测试上下文里显式注入占位符配置器,关闭忽略规则:

@TestConfiguration
public class TestPlaceholderConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setIgnoreUnresolvablePlaceholders(false);
        return configurer;
    }
}

然后把这个配置类加到@SpringBootTest的classes属性里,单元测试就会和正式环境一样抛出找不到val的异常。

内容的提问来源于stack exchange,提问作者Andre Peng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 19:39:04