假设我想依靠PostgreSQL testcontainer
将Spring Boot 2.x应用程序中依赖JPA数据源的测试代码集成在一起(使用一或几行代码从测试类中管理Docker容器的绝佳工具)。进一步假设我正在管理application.properties
中的端口(包括在JDBC URL中),例如
spring.datasource.url=jdbc:postgresql://user-service-postgres:5432/user_service
在集成测试中,我使用以下方式创建测试容器
@Rule
PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer();
在准备方法中,我可以使用
访问要为spring.datasource.url
设置的值
postgreSQLContainer.getJdbcUrl()
如何在测试中告诉Spring Boot使用该URL而不是application.properties
中指定的URL。
我想坚持使用我的属性文件以最小化更改,但是我感谢其他方法,包括解释为什么它们也很出色或必要的原因。
我正在使用Spring Boot 2.x。
答案 0 :(得分:2)
从Spring Framework 5.2.5(Spring Boot 2.2.6)开始,此设置现在变得更加简单,因为我们可以使用@DynamicPropertySource
批注,而不必编写和注册自定义初始化程序。
假设您使用的是Testcontainers的JUnit 5依赖项,那么您的测试将如下所示:
@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {
@Container
static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer();
@DynamicPropertySource
static void dataSourceProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
}
}
您可以阅读有关此新功能here的更多信息。我还在dedicated Testcontainers guide中介绍了不同的应用程序属性设置方式(取决于Spring Boot和JUnit版本)。
答案 1 :(得分:1)
您可以使用ContextConfiguration
和ApplicationContextInitializer
在Spring-boot测试中手动覆盖属性。
覆盖属性-定义一个静态内部类:
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("spring.datasource.url=" + postgreSQLContainer.getJdbcUrl())
.applyTo(configurableApplicationContext.getEnvironment());
}
}
ApplicationContextInitializer
可用于在上下文刷新之前以编程方式初始化Spring上下文。现在,通过在测试类级别使用ContextConfiguration
进行注释来连接上下文初始化器类:
@ContextConfiguration(initializers = Initializer.class)
文档: