Spring Framework 5.2.5 和 Spring Boot 2.2.6 中的 @DynamicPropertySource

工程 | Andy Wilkinson | 2020年3月27日 | ...

最近,在 Spring IO 和 SpringOne Platform 上讨论 Spring Boot 应用程序的测试时,我提到了 Testcontainers讨论 了配置测试以使用容器内服务的样板代码。我很高兴地宣布,随着 Spring Framework 5.2.5 的最新发布,这种样板代码已不再需要。

在我们刚刚发布的更改之前,您的集成测试看起来会像下面这样

@SpringBootTest
@Testcontainers
@ContextConfiguration(initializers = ExampleIntegrationTests.Initializer.class)
class ExampleIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>();

    static class Initializer implements
            ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext context) {
            TestPropertyValues.of("spring.data.neo4j.uri=" + neo4j.getBoltUrl())
                    .applyTo(context.getEnvironment());
        }

    }

}

这里我们使用 @ContextConfiguration 来指定一个 ApplicationContextInitializer。该初始化器将 spring.data.neo4j.uri 属性设置为 Neo4j 容器的 bolt URL 值。这使得我们应用程序中与 Neo4j 相关的 bean 能够与 Testcontainers 管理的 Docker 容器中运行的 Neo4j 进行通信。

得益于 Spring Framework 5.2.5 中的更改,可以使用一个静态的 @DynamicPropertySource 方法来替代 @ContextConfigurationApplicationContextInitializer,达到相同的目的。如果我们将上面显示的集成测试类进行这些更改,它现在看起来会像下面这样

@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>();

    @DynamicPropertySource
    static void neo4jProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
    }

}

我们将代码量减少了三分之一,而且意图也希望更加清晰。

虽然新功能受到了让 Testcontainers 在 Spring Boot 集成测试中更易于使用的启发,但它应该对任何 Spring 集成测试都很有用,在这些测试中,属性的值无法提前知道。您可以在 Spring Framework 参考文档 中了解更多关于 @DynamicPropertySource 的信息。

祝集成测试愉快!

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有