覆盖单个 Spring Boot 测试的属性

Posted

技术标签:

【中文标题】覆盖单个 Spring Boot 测试的属性【英文标题】:Override a property for a single Spring Boot test 【发布时间】:2018-07-12 06:01:54 【问题描述】:

考虑以下示例:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    properties = 
        "some.property=valueA"
    )
public class ServiceTest 
    @Test
    public void testA()  ... 

    @Test
    public void testB()  ... 

    @Test
    public void testC()  ... 

我正在使用SpringBootTest 注释的properties 属性为该测试套件中的所有测试设置some.property 属性值。现在我想在不影响其他测试的情况下为其中一个测试(比如说testC)设置此属性的另一个值。我怎样才能做到这一点?我已经阅读了"Testing" chapter of Spring Boot docs,但没有找到任何符合我用例的内容。

【问题讨论】:

如果只需要配置几个属性,可以使用新的@DynamicPropertySource 注解。 ***.com/a/60941845/8650621 【参考方案1】:

您的属性在 Spring 上下文加载期间由 Spring 评估。 所以容器启动后就不能再更改了。

作为解决方法,您可以将方法拆分为多个类,从而创建它们自己的 Spring 上下文。 但要小心,因为测试执行速度应该很快。

更好的方法是在被测类中有一个 setter 来注入 some.property 值并在测试中使用此方法以编程方式更改值。

private String someProperty;

@Value("$some.property")
public void setSomeProperty(String someProperty) 
    this.someProperty = someProperty;

【讨论】:

【参考方案2】:

更新

可以使用 Spring 5.2.5 和 Spring Boot 2.2.6

@DynamicPropertySource
static void dynamicProperties(DynamicPropertyRegistry registry) 
    registry.add("some.property", () -> "valueA");

【讨论】:

【参考方案3】:

如果您使用@ConfigurationProperties,这只是另一种解决方案:

@Test
void do_stuff(@Autowired MyProperties properties)
  properties.setSomething(...);
  ...

【讨论】:

我认为如果这个方法首先运行,这个类中的所有其他测试也会改变。 我猜是这样,但我们也可以将属性自动连接到 setup 方法中并在那里设置默认值

以上是关于覆盖单个 Spring Boot 测试的属性的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.1 bean 覆盖与 Primary

使用 spring-boot 存储库返回单个属性

Spring Boot - 不覆盖服务器端口属性

通过环境变量覆盖 Spring Boot yaml 属性

springboot 复制属性BeanUtils.copyProperties

用于 Spring Boot 中测试的 Gradle 命令行参数