Skip to content

Provide a mechanism to configure integration tests with a dynamic property source #24540

@wilkinsona

Description

@wilkinsona

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.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions