覆盖单个 Spring 启动测试的属性



请考虑以下示例:

@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(设置此属性的另一个值,而不会影响其他测试。我怎样才能做到这一点?我已经阅读了Spring Boot文档的"测试"一章,但我还没有找到任何与我的用例相匹配的内容。

在 Spring 上下文加载期间,Spring 会评估您的属性。
因此,在容器启动后无法更改它们。

作为解决方法,您可以将方法拆分为多个类,从而创建自己的 Spring 上下文。但要注意,因为这可能是一个坏主意,因为测试执行应该很快。

更好的方法可能是在被测类中有一个二传手注入some.property值,并在测试中使用此方法以编程方式更改值。

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

更新

至少在 Spring 5.2.5 和 Spring Boot 2.2.6 中可能

@DynamicPropertySource
static void dynamicProperties(DynamicPropertyRegistry registry) {
    registry.add("some.property", () -> "valueA");
}
如果您

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

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

使用 JUnit 5,您应该能够通过使用嵌套测试来减少必要的代码。将默认配置添加到外部测试类,并将重写注释添加到嵌套测试。

另请参阅:

  • 如何将嵌套测试与 spring-test-junit5 一起使用?
  • https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested

我在一次集成测试中遇到了同样的问题,但我更喜欢在我的代码中使用@ConfigurationProperties,这是这里的关键。

在尝试通过各种其他方法设置属性后,我意识到我可以自动连接我的属性类,并简单地在每个特定测试中设置我想要的值。

注意:如果这是一个单元测试,我将能够同样轻松地模拟我的属性类。

最新更新