Remove most deprecated APIs that were due for removal in 4.0

Support for rest controller, controler, and servlet endpoints has
been kept for now.

Issue: 45600
This commit is contained in:
Andy Wilkinson
2025-06-10 20:11:08 +01:00
committed by Phillip Webb
parent bf385649ec
commit a78797a2ba
192 changed files with 94 additions and 10953 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,6 @@
package org.springframework.boot.testcontainers.properties;
import java.util.ArrayList;
import java.util.List;
import com.redis.testcontainers.RedisContainer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -32,7 +29,6 @@ import org.springframework.boot.testsupport.container.DisabledIfDockerUnavailabl
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;
@@ -55,59 +51,6 @@ class TestcontainersPropertySourceAutoConfigurationTests {
.withInitializer(new TestcontainersLifecycleApplicationContextInitializer())
.withConfiguration(AutoConfigurations.of(TestcontainersPropertySourceAutoConfiguration.class));
@Test
@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(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) -> {

View File

@@ -27,7 +27,6 @@ import org.springframework.boot.testcontainers.properties.TestcontainersProperty
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;
@@ -45,11 +44,6 @@ class TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegration
@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");
@@ -60,12 +54,6 @@ class TestcontainersPropertySourceAutoConfigurationWithSpringBootTestIntegration
@SpringBootConfiguration
static class TestConfig {
@Bean
String example(DynamicPropertyRegistry registry) {
registry.add("from.bean.method", () -> "one");
return "Hello";
}
@Bean
DynamicPropertyRegistrar propertyRegistrar() {
return (registry) -> registry.add("from.registrar", () -> "two");

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.testcontainers.lifecycle;
import org.testcontainers.containers.Container;
import org.springframework.context.ApplicationEvent;
import org.springframework.test.context.DynamicPropertyRegistrar;
/**
* Event published just before a Testcontainers {@link Container} is used.
*
* @author Andy Wilkinson
* @since 3.2.6
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of property registration using a
* {@link DynamicPropertyRegistrar} bean that injects the {@link Container} from which the
* properties will be sourced.
*/
@Deprecated(since = "3.4.0", forRemoval = true)
public class BeforeTestcontainerUsedEvent extends ApplicationEvent {
public BeforeTestcontainerUsedEvent(Object source) {
super(source);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,6 @@ public class TestcontainersLifecycleApplicationContextInitializer
TestcontainersLifecycleBeanPostProcessor beanPostProcessor = new TestcontainersLifecycleBeanPostProcessor(
beanFactory, startup);
beanFactory.addBeanPostProcessor(beanPostProcessor);
applicationContext.addApplicationListener(beanPostProcessor);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.ApplicationListener;
import org.springframework.context.aot.AbstractAotProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@@ -59,10 +58,8 @@ import org.springframework.core.log.LogMessage;
* @author Scott Frederick
* @see TestcontainersLifecycleApplicationContextInitializer
*/
@SuppressWarnings({ "removal", "deprecation" })
@Order(Ordered.LOWEST_PRECEDENCE)
class TestcontainersLifecycleBeanPostProcessor
implements DestructionAwareBeanPostProcessor, ApplicationListener<BeforeTestcontainerUsedEvent> {
class TestcontainersLifecycleBeanPostProcessor implements DestructionAwareBeanPostProcessor {
private static final Log logger = LogFactory.getLog(TestcontainersLifecycleBeanPostProcessor.class);
@@ -80,12 +77,6 @@ class TestcontainersLifecycleBeanPostProcessor
this.startup = startup;
}
@Override
@Deprecated(since = "3.4.0", forRemoval = true)
public void onApplicationEvent(BeforeTestcontainerUsedEvent event) {
initializeContainers();
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (this.beanFactory.isConfigurationFrozen() && !isAotProcessingInProgress()) {

View File

@@ -1,208 +0,0 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.testcontainers.properties;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testcontainers.containers.Container;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.test.context.DynamicPropertyRegistrar;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.util.Assert;
import org.springframework.util.function.SupplierUtils;
/**
* {@link EnumerablePropertySource} backed by a map with values supplied from one or more
* {@link Container testcontainers}.
*
* @author Phillip Webb
* @since 3.1.0
* @deprecated since 3.4.0 for removal in 4.0.0 in favor of declaring one or more
* {@link DynamicPropertyRegistrar} beans.
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
public class TestcontainersPropertySource extends MapPropertySource {
private static final Log logger = LogFactory.getLog(TestcontainersPropertySource.class);
static final String NAME = "testcontainersPropertySource";
private final DynamicPropertyRegistry registry;
private final Set<ApplicationEventPublisher> eventPublishers = new CopyOnWriteArraySet<>();
TestcontainersPropertySource(DynamicPropertyRegistryInjection registryInjection) {
this(Collections.synchronizedMap(new LinkedHashMap<>()), registryInjection);
}
private TestcontainersPropertySource(Map<String, Supplier<Object>> valueSuppliers,
DynamicPropertyRegistryInjection registryInjection) {
super(NAME, Collections.unmodifiableMap(valueSuppliers));
this.registry = (name, valueSupplier) -> {
Assert.hasText(name, "'name' must not be empty");
DynamicPropertyRegistryInjectionException.throwIfNecessary(name, registryInjection);
Assert.notNull(valueSupplier, "'valueSupplier' must not be null");
valueSuppliers.put(name, valueSupplier);
};
}
private void addEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublishers.add(eventPublisher);
}
@Override
public Object getProperty(String name) {
Object valueSupplier = this.source.get(name);
return (valueSupplier != null) ? getProperty(name, valueSupplier) : null;
}
private Object getProperty(String name, Object valueSupplier) {
BeforeTestcontainerUsedEvent event = new BeforeTestcontainerUsedEvent(this);
this.eventPublishers.forEach((eventPublisher) -> eventPublisher.publishEvent(event));
return SupplierUtils.resolve(valueSupplier);
}
public static DynamicPropertyRegistry attach(Environment environment) {
return attach(environment, null);
}
static DynamicPropertyRegistry attach(ConfigurableApplicationContext applicationContext) {
return attach(applicationContext.getEnvironment(), applicationContext, null);
}
public static DynamicPropertyRegistry attach(Environment environment, BeanDefinitionRegistry registry) {
return attach(environment, null, registry);
}
private static DynamicPropertyRegistry attach(Environment environment, ApplicationEventPublisher eventPublisher,
BeanDefinitionRegistry registry) {
Assert.state(environment instanceof ConfigurableEnvironment,
"TestcontainersPropertySource can only be attached to a ConfigurableEnvironment");
TestcontainersPropertySource propertySource = getOrAdd((ConfigurableEnvironment) environment);
if (eventPublisher != null) {
propertySource.addEventPublisher(eventPublisher);
}
else if (registry != null && !registry.containsBeanDefinition(EventPublisherRegistrar.NAME)) {
registry.registerBeanDefinition(EventPublisherRegistrar.NAME, new RootBeanDefinition(
EventPublisherRegistrar.class, () -> new EventPublisherRegistrar(environment)));
}
return propertySource.registry;
}
static TestcontainersPropertySource getOrAdd(ConfigurableEnvironment environment) {
PropertySource<?> propertySource = environment.getPropertySources().get(NAME);
if (propertySource == null) {
BindResult<DynamicPropertyRegistryInjection> bindingResult = Binder.get(environment)
.bind("spring.testcontainers.dynamic-property-registry-injection",
DynamicPropertyRegistryInjection.class);
environment.getPropertySources()
.addFirst(
new TestcontainersPropertySource(bindingResult.orElse(DynamicPropertyRegistryInjection.FAIL)));
return getOrAdd(environment);
}
Assert.state(propertySource instanceof TestcontainersPropertySource,
"Incorrect TestcontainersPropertySource type registered");
return ((TestcontainersPropertySource) propertySource);
}
/**
* {@link BeanFactoryPostProcessor} to register the {@link ApplicationEventPublisher}
* to the {@link TestcontainersPropertySource}. This class is a
* {@link BeanFactoryPostProcessor} so that it is initialized as early as possible.
*/
static class EventPublisherRegistrar implements BeanFactoryPostProcessor, ApplicationEventPublisherAware {
static final String NAME = EventPublisherRegistrar.class.getName();
private final Environment environment;
private ApplicationEventPublisher eventPublisher;
EventPublisherRegistrar(Environment environment) {
this.environment = environment;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.eventPublisher != null) {
TestcontainersPropertySource.getOrAdd((ConfigurableEnvironment) this.environment)
.addEventPublisher(this.eventPublisher);
}
}
}
private enum DynamicPropertyRegistryInjection {
ALLOW,
FAIL,
WARN
}
static final class DynamicPropertyRegistryInjectionException extends RuntimeException {
private DynamicPropertyRegistryInjectionException(String propertyName) {
super("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated. Register '"
+ propertyName + "' using a DynamicPropertyRegistrar bean instead. Alternatively, set "
+ "spring.testcontainers.dynamic-property-registry-injection to 'warn' to replace this "
+ "failure with a warning or to 'allow' to permit injection of the registry.");
}
private static void throwIfNecessary(String propertyName, DynamicPropertyRegistryInjection registryInjection) {
switch (registryInjection) {
case FAIL -> throw new DynamicPropertyRegistryInjectionException(propertyName);
case WARN -> logger
.warn("Support for injecting a DynamicPropertyRegistry into @Bean methods is deprecated. Register '"
+ propertyName + "' using a DynamicPropertyRegistrar bean instead.");
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Role;
import org.springframework.core.Ordered;
@@ -44,13 +43,6 @@ import org.springframework.test.context.support.DynamicPropertyRegistrarBeanInit
@ConditionalOnClass(DynamicPropertyRegistry.class)
public class TestcontainersPropertySourceAutoConfiguration {
@Bean
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
static DynamicPropertyRegistry dynamicPropertyRegistry(ConfigurableApplicationContext applicationContext) {
return TestcontainersPropertySource.attach(applicationContext);
}
@Bean
@ConditionalOnMissingBean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)

View File

@@ -1,163 +0,0 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.testcontainers.properties;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.testcontainers.lifecycle.BeforeTestcontainerUsedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.DynamicPropertyRegistry;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link TestcontainersPropertySource}.
*
* @author Phillip Webb
* @deprecated since 3.4.0 for removal in 4.0.0
*/
@SuppressWarnings("removal")
@Deprecated(since = "3.4.0", forRemoval = true)
class TestcontainersPropertySourceTests {
private MockEnvironment environment = new MockEnvironment()
.withProperty("spring.testcontainers.dynamic-property-registry-injection", "allow");
private GenericApplicationContext context = new GenericApplicationContext();
TestcontainersPropertySourceTests() {
((DefaultListableBeanFactory) this.context.getBeanFactory()).setAllowBeanDefinitionOverriding(false);
this.context.setEnvironment(this.environment);
}
@Test
void getPropertyWhenHasValueSupplierReturnsSuppliedValue() {
DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment);
registry.add("test", () -> "spring");
assertThat(this.environment.getProperty("test")).isEqualTo("spring");
}
@Test
void getPropertyWhenHasNoValueSupplierReturnsNull() {
DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment);
registry.add("test", () -> "spring");
assertThat(this.environment.getProperty("missing")).isNull();
}
@Test
void containsPropertyWhenHasPropertyReturnsTrue() {
DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment);
registry.add("test", () -> null);
assertThat(this.environment.containsProperty("test")).isTrue();
}
@Test
void containsPropertyWhenHasNoPropertyReturnsFalse() {
DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment);
registry.add("test", () -> null);
assertThat(this.environment.containsProperty("missing")).isFalse();
}
@Test
void getPropertyNamesReturnsNames() {
DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(this.environment);
registry.add("test", () -> null);
registry.add("other", () -> null);
EnumerablePropertySource<?> propertySource = (EnumerablePropertySource<?>) this.environment.getPropertySources()
.get(TestcontainersPropertySource.NAME);
assertThat(propertySource.getPropertyNames()).containsExactly("test", "other");
}
@Test
@SuppressWarnings("unchecked")
void getSourceReturnsImmutableSource() {
TestcontainersPropertySource.attach(this.environment);
PropertySource<?> propertySource = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
Map<String, Object> map = (Map<String, Object>) propertySource.getSource();
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(map::clear);
}
@Test
void attachToEnvironmentWhenNotAttachedAttaches() {
TestcontainersPropertySource.attach(this.environment);
PropertySource<?> propertySource = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
assertThat(propertySource).isNotNull();
}
@Test
void attachToEnvironmentWhenAlreadyAttachedReturnsExisting() {
DynamicPropertyRegistry r1 = TestcontainersPropertySource.attach(this.environment);
PropertySource<?> p1 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
DynamicPropertyRegistry r2 = TestcontainersPropertySource.attach(this.environment);
PropertySource<?> p2 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
assertThat(r1).isSameAs(r2);
assertThat(p1).isSameAs(p2);
}
@Test
void attachToEnvironmentAndContextWhenNotAttachedAttaches() {
TestcontainersPropertySource.attach(this.environment, this.context);
PropertySource<?> propertySource = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
assertThat(propertySource).isNotNull();
assertThat(this.context.containsBean(
org.springframework.boot.testcontainers.properties.TestcontainersPropertySource.EventPublisherRegistrar.NAME));
}
@Test
void attachToEnvironmentAndContextWhenAlreadyAttachedReturnsExisting() {
DynamicPropertyRegistry r1 = TestcontainersPropertySource.attach(this.environment, this.context);
PropertySource<?> p1 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
DynamicPropertyRegistry r2 = TestcontainersPropertySource.attach(this.environment, this.context);
PropertySource<?> p2 = this.environment.getPropertySources().get(TestcontainersPropertySource.NAME);
assertThat(r1).isSameAs(r2);
assertThat(p1).isSameAs(p2);
}
@Test
void getPropertyPublishesEvent() {
try (GenericApplicationContext applicationContext = new GenericApplicationContext()) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
environment.getPropertySources()
.addLast(new MapPropertySource("test",
Map.of("spring.testcontainers.dynamic-property-registry-injection", "allow")));
List<ApplicationEvent> events = new ArrayList<>();
applicationContext.addApplicationListener(events::add);
DynamicPropertyRegistry registry = TestcontainersPropertySource.attach(environment,
(BeanDefinitionRegistry) applicationContext.getBeanFactory());
applicationContext.refresh();
registry.add("test", () -> "spring");
assertThat(environment.containsProperty("test")).isTrue();
assertThat(events.isEmpty());
assertThat(environment.getProperty("test")).isEqualTo("spring");
assertThat(events.stream().filter(BeforeTestcontainerUsedEvent.class::isInstance)).hasSize(1);
}
}
}