-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Description
In Spring Boot, we'd like to make it easier to set configuration properties from something else that's bootstrapped as part of running an integration test. The main use case that we have for this is setting configuration properties based on the IP address and port on which a Testcontainers container is listening.
The current solution requires using an ApplicationContextInitializer
to manipulate the Environment
:
@Testcontainers
@ContextConfiguration(initializers = DataRedisTestIntegrationTests.Initializer.class)
@DataRedisTest
public class DataRedisTestIntegrationTests {
@Container
public static RedisContainer redis = new RedisContainer();
// …
static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(
ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of(
"spring.redis.host=" + redis.getContainerIpAddress(),
"spring.redis.port=" + redis.getMappedPort()
).applyTo(configurableApplicationContext.getEnvironment());
}
}
}
We'd like to make this more of a first-class concept. One proposal is to achieve that via a method on the test class that can provide a property source:
@Testcontainers
@DataRedisTest
class DataRedisTestIntegrationTests {
@Container
static RedisContainer redis = new RedisContainer();
// …
@DynamicPropertySource
static PropertySource redisProperties() {
return TestPropertyValues.of(
"spring.redis.host=" + redis.getContainerIpAddress(),
"spring.redis.port=" + redis.getMappedPort()
).asPropertySource();
}
}
There are some interesting ordering considerations here. It requires the RedisContainer
to have been started and assigned to redis
before the redisProperties()
method is called. To some extent at least, this is already a solved problem as the more cumbersome ApplicationContextInitializer
approach shown above works today.