You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何@Nested测试类无法读取@TestPropertySource的覆盖配置?

Spring Boot嵌套集成测试@TestPropertySource不生效的原因

问题重现

你编写的测试代码如下:

@TestPropertySource(properties = {"spring.application.environment=dev"})
@SpringBootTest
class IntegrationTest  {

    @Autowired
    PropertyConfig propertyConfig;

    @Nested
    @SpringBootTest
    @TestPropertySource(properties = {"spring.application.environment=dev", "spring.application.property=example"})
    class ServerLoadConfiguration  {
        
        @Test
        void exampleTest() {
            String someProperty = propertyConfig.getSomeProperty(); // 获取到的是旧值,不是覆盖后的example
            ....
        }
    }
}

问题:嵌套类ServerLoadConfiguration的exampleTest中,读取到的属性是默认值而非@TestPropertySource指定的覆盖值,但把该@TestPropertySource移到外层IntegrationTest类上时,嵌套类就能读到覆盖值。

原因解析

这核心是Spring Boot测试上下文的创建规则和嵌套类的bean作用域问题:

  • 外层IntegrationTest标注了@SpringBootTest,会初始化一个独立的Spring上下文,加载外层的@TestPropertySource配置,并把propertyConfig注入到外层类的字段中。
  • 嵌套类ServerLoadConfiguration也标注了@SpringBootTest,这会触发创建另一个全新的独立上下文,这个上下文确实会加载嵌套类自己的@TestPropertySource配置。但你在exampleTest里调用的propertyConfig是外层类已经注入好的实例——它属于外层的旧上下文,和嵌套类的新上下文完全无关,自然读不到新的属性值。
  • 当你把@TestPropertySource移到外层类时,外层上下文会直接加载覆盖后的属性,嵌套类的@SpringBootTest默认会继承外层的测试配置(包括属性),所以此时无论是复用上下文还是新创建的上下文,都会使用外层的属性配置,自然能读到覆盖值。

解决办法

有两种常用的修复方式:

  • 把propertyConfig注入到嵌套类中:在ServerLoadConfiguration类里重新添加@Autowired PropertyConfig propertyConfig;,这样会从嵌套类的新上下文中获取bean实例,就能读到覆盖后的属性。
  • 去掉嵌套类上的@SpringBootTest:这样嵌套类会直接复用外层的上下文,此时如果嵌套类有自己的@TestPropertySource,会在原有上下文的基础上覆盖属性,也能读到正确的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:00:59