Prefer DynamicPropertyRegistar to DynamicPropertyRegistry

Closes gh-41996
This commit is contained in:
Andy Wilkinson
2024-09-25 13:54:43 +01:00
parent fdc4a51e24
commit 3c095b4ec2
18 changed files with 341 additions and 77 deletions

View File

@@ -103,7 +103,7 @@ class ImportTestcontainersTests {
void importWhenHasContainerDefinitionsWithDynamicPropertySource() {
this.applicationContext = new AnnotationConfigApplicationContext(
ContainerDefinitionsWithDynamicPropertySource.class);
assertThat(this.applicationContext.getEnvironment().containsProperty("container.port")).isTrue();
assertThat(this.applicationContext.getEnvironment().getProperty("container.port")).isNotNull();
}
@Test

View File

@@ -21,19 +21,22 @@ import java.util.List;
import com.redis.testcontainers.RedisContainer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent;
import org.springframework.boot.testcontainers.lifecycle.TestcontainersLifecycleApplicationContextInitializer;
import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailable;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.system.CapturedOutput;
import org.springframework.boot.testsupport.system.OutputCaptureExtension;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.DynamicPropertyRegistrar;
import org.springframework.test.context.DynamicPropertyRegistry;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,8 +45,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link TestcontainersPropertySourceAutoConfiguration}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
@DisabledIfDockerUnavailable
@ExtendWith(OutputCaptureExtension.class)
class TestcontainersPropertySourceAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
@@ -51,18 +56,67 @@ class TestcontainersPropertySourceAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(TestcontainersPropertySourceAutoConfiguration.class));
@Test
void containerBeanMethodContributesProperties() {
List<ApplicationEvent> events = new ArrayList<>();
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
void registeringADynamicPropertyFailsByDefault() {
this.contextRunner.withUserConfiguration(ContainerAndPropertiesConfiguration.class)
.run((context) -> assertThat(context).getFailure()
.rootCause()
.isInstanceOf(
org.springframework.boot.testcontainers.properties.TestcontainersPropertySource.DynamicPropertyRegistryInjectionException.class)
.hasMessageStartingWith(
"Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated"));
}
@Test
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
void registeringADynamicPropertyCanLogAWarningAndContributeProperty(CapturedOutput output) {
List<ApplicationEvent> events = new ArrayList<>();
this.contextRunner.withPropertyValues("spring.testcontainers.dynamic-property-registry-injection=warn")
.withUserConfiguration(ContainerAndPropertiesConfiguration.class)
.withInitializer((context) -> context.addApplicationListener(events::add))
.run((context) -> {
TestBean testBean = context.getBean(TestBean.class);
RedisContainer redisContainer = context.getBean(RedisContainer.class);
assertThat(testBean.getUsingPort()).isEqualTo(redisContainer.getFirstMappedPort());
assertThat(events.stream().filter(BeforeTestcontainerUsedEvent.class::isInstance)).hasSize(1);
assertThat(events.stream()
.filter(org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent.class::isInstance))
.hasSize(1);
assertThat(output)
.contains("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated");
});
}
@Test
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
void registeringADynamicPropertyCanBePermittedAndContributeProperty(CapturedOutput output) {
List<ApplicationEvent> events = new ArrayList<>();
this.contextRunner.withPropertyValues("spring.testcontainers.dynamic-property-registry-injection=allow")
.withUserConfiguration(ContainerAndPropertiesConfiguration.class)
.withInitializer((context) -> context.addApplicationListener(events::add))
.run((context) -> {
TestBean testBean = context.getBean(TestBean.class);
RedisContainer redisContainer = context.getBean(RedisContainer.class);
assertThat(testBean.getUsingPort()).isEqualTo(redisContainer.getFirstMappedPort());
assertThat(events.stream()
.filter(org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent.class::isInstance))
.hasSize(1);
assertThat(output)
.doesNotContain("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated");
});
}
@Test
void dynamicPropertyRegistrarBeanContributesProperties(CapturedOutput output) {
this.contextRunner.withUserConfiguration(ContainerAndPropertyRegistrarConfiguration.class).run((context) -> {
TestBean testBean = context.getBean(TestBean.class);
RedisContainer redisContainer = context.getBean(RedisContainer.class);
assertThat(testBean.getUsingPort()).isEqualTo(redisContainer.getFirstMappedPort());
});
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ContainerProperties.class)
@Import(TestBean.class)
@@ -77,6 +131,23 @@ class TestcontainersPropertySourceAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ContainerProperties.class)
@Import(TestBean.class)
static class ContainerAndPropertyRegistrarConfiguration {
@Bean
RedisContainer redisContainer() {
return TestImage.container(RedisContainer.class);
}
@Bean
DynamicPropertyRegistrar redisProperties(RedisContainer container) {
return (registry) -> registry.add("container.port", container::getFirstMappedPort);
}
}
@ConfigurationProperties("container")
record ContainerProperties(int port) {
}

View File

@@ -18,26 +18,41 @@ package org.springframework.boot.testcontainers.properties;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.properties.TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegrationTest.TestConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.test.context.DynamicPropertyRegistrar;
import org.springframework.test.context.DynamicPropertyRegistry;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link TestcontainersPropertySourceAutoConfiguration} when combined with
* {@link SpringBootTest @SpringBootTest}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
@SpringBootTest(classes = TestConfig.class)
@SpringBootTest(classes = TestConfig.class,
properties = "spring.testcontainers.dynamic-property-registry-injection=allow")
class TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegrationTest {
@Test
void injectsRegistry() {
@Autowired
private Environment environment;
@Test
void injectsRegistryIntoBeanMethod() {
assertThat(this.environment.getProperty("from.bean.method")).isEqualTo("one");
}
@Test
void callsRegistrars() {
assertThat(this.environment.getProperty("from.registrar")).isEqualTo("two");
}
@TestConfiguration
@@ -47,10 +62,15 @@ class TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegration
@Bean
String example(DynamicPropertyRegistry registry) {
registry.add("test", () -> "test");
registry.add("from.bean.method", () -> "one");
return "Hello";
}
@Bean
DynamicPropertyRegistrar propertyRegistrar() {
return (registry) -> registry.add("from.registrar", () -> "two");
}
}
}