diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java index bcd71ba404..2d1a767f24 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java @@ -231,15 +231,15 @@ public class ArtemisAutoConfigurationTests { "spring.artemis.embedded.dataDirectory:" + dataFolder.getAbsolutePath()) .run((context) -> context.getBean(JmsTemplate.class).send("TestQueue", - (session) -> session.createTextMessage(messageId))); - // Start the server again and check if our message is still here - this.contextRunner.run((context) -> { - JmsTemplate jmsTemplate2 = context.getBean(JmsTemplate.class); - jmsTemplate2.setReceiveTimeout(1000L); - Message message = jmsTemplate2.receive("TestQueue"); - assertThat(message).isNotNull(); - assertThat(((TextMessage) message).getText()).isEqualTo(messageId); - }); + (session) -> session.createTextMessage(messageId))) + .run((context) -> { + // Start the server again and check if our message is still here + JmsTemplate jmsTemplate2 = context.getBean(JmsTemplate.class); + jmsTemplate2.setReceiveTimeout(1000L); + Message message = jmsTemplate2.receive("TestQueue"); + assertThat(message).isNotNull(); + assertThat(((TextMessage) message).getText()).isEqualTo(messageId); + }); } @Test diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfigurationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfigurationTests.java index b688c00c64..1ab50dcb73 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfigurationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfigurationTests.java @@ -55,7 +55,9 @@ public class TestDatabaseAutoConfigurationTests { DataSource datasource = context.getBean(DataSource.class); JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource); jdbcTemplate.execute("create table example (id int, name varchar);"); - this.contextRunner.run((secondContext) -> { + this.contextRunner + .withUserConfiguration(ExistingDataSourceConfiguration.class) + .run((secondContext) -> { DataSource anotherDatasource = secondContext .getBean(DataSource.class); JdbcTemplate anotherJdbcTemplate = new JdbcTemplate( diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java index f22f6f7a81..37d54d125c 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/AbstractApplicationContextRunner.java @@ -17,6 +17,7 @@ package org.springframework.boot.test.context.runner; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.function.Supplier; @@ -98,25 +99,48 @@ abstract class AbstractApplicationContextRunner contextFactory; - private TestPropertyValues environmentProperties; + private final TestPropertyValues environmentProperties; - private TestPropertyValues systemProperties; + private final TestPropertyValues systemProperties; - private ClassLoader classLoader; + private final ClassLoader classLoader; - private ApplicationContext parent; + private final ApplicationContext parent; - private final List configurations = new ArrayList<>(); + private final List configurations; /** * Create a new {@link AbstractApplicationContextRunner} instance. * @param contextFactory the factory used to create the actual context */ protected AbstractApplicationContextRunner(Supplier contextFactory) { + this(contextFactory, TestPropertyValues.empty(), TestPropertyValues.empty(), null, + null, Collections.emptyList()); + } + + /** + * Create a new {@link AbstractApplicationContextRunner} instance. + * @param contextFactory the factory used to create the actual context + * @param environmentProperties the environment properties + * @param systemProperties the system properties + * @param classLoader the class loader + * @param parent the parent + * @param configurations the configuration + */ + protected AbstractApplicationContextRunner(Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { Assert.notNull(contextFactory, "ContextFactory must not be null"); + Assert.notNull(environmentProperties, "EnvironmentProperties must not be null"); + Assert.notNull(systemProperties, "SystemProperties must not be null"); + Assert.notNull(configurations, "Configurations must not be null"); this.contextFactory = contextFactory; - this.environmentProperties = TestPropertyValues.empty(); - this.systemProperties = TestPropertyValues.empty(); + this.environmentProperties = environmentProperties; + this.systemProperties = systemProperties; + this.classLoader = classLoader; + this.parent = parent; + this.configurations = Collections.unmodifiableList(configurations); } /** @@ -125,13 +149,14 @@ abstract class AbstractApplicationContextRunner... configurationClasses) { return withConfiguration(UserConfigurations.of(configurationClasses)); @@ -186,32 +212,42 @@ abstract class AbstractApplicationContextRunner List add(List list, T element) { + List result = new ArrayList<>(list); + result.add(element); + return result; } + protected abstract SELF newInstance(Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations); + /** * Create and refresh a new {@link ApplicationContext} based on the current state of * this loader. The context is consumed by the specified {@code consumer} and closed * upon completion. * @param consumer the consumer of the created {@link ApplicationContext} + * @return this instance */ - public void run(ContextConsumer consumer) { + @SuppressWarnings("unchecked") + public SELF run(ContextConsumer consumer) { this.systemProperties.applyToSystemProperties(() -> { try (A context = createAssertableContext()) { accept(consumer, context); } return null; }); + return (SELF) this; } @SuppressWarnings("unchecked") diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ApplicationContextRunner.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ApplicationContextRunner.java index d3799554bd..52278569b9 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ApplicationContextRunner.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ApplicationContextRunner.java @@ -16,9 +16,13 @@ package org.springframework.boot.test.context.runner; +import java.util.List; import java.util.function.Supplier; +import org.springframework.boot.context.annotation.Configurations; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -54,4 +58,23 @@ public class ApplicationContextRunner extends super(contextFactory); } + private ApplicationContextRunner( + Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { + super(contextFactory, environmentProperties, systemProperties, classLoader, + parent, configurations); + } + + @Override + protected ApplicationContextRunner newInstance( + Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { + return new ApplicationContextRunner(contextFactory, environmentProperties, + systemProperties, classLoader, parent, configurations); + } + } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java index 07ec6fc2fd..431682e2f5 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/ReactiveWebApplicationContextRunner.java @@ -16,11 +16,15 @@ package org.springframework.boot.test.context.runner; +import java.util.List; import java.util.function.Supplier; +import org.springframework.boot.context.annotation.Configurations; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; +import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext; +import org.springframework.context.ApplicationContext; /** * A {@link AbstractApplicationContextRunner ApplicationContext runner} for a @@ -54,4 +58,24 @@ public final class ReactiveWebApplicationContextRunner extends super(contextFactory); } + private ReactiveWebApplicationContextRunner( + Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { + super(contextFactory, environmentProperties, systemProperties, classLoader, + parent, configurations); + } + + @Override + protected ReactiveWebApplicationContextRunner newInstance( + Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { + return new ReactiveWebApplicationContextRunner(contextFactory, + environmentProperties, systemProperties, classLoader, parent, + configurations); + } + } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java index ea3e9b1c54..beb245bb2d 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/runner/WebApplicationContextRunner.java @@ -16,9 +16,13 @@ package org.springframework.boot.test.context.runner; +import java.util.List; import java.util.function.Supplier; +import org.springframework.boot.context.annotation.Configurations; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContext; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.ConfigurableWebApplicationContext; import org.springframework.web.context.WebApplicationContext; @@ -58,6 +62,25 @@ public final class WebApplicationContextRunner extends super(contextFactory); } + private WebApplicationContextRunner( + Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { + super(contextFactory, environmentProperties, systemProperties, classLoader, + parent, configurations); + } + + @Override + protected WebApplicationContextRunner newInstance( + Supplier contextFactory, + TestPropertyValues environmentProperties, TestPropertyValues systemProperties, + ClassLoader classLoader, ApplicationContext parent, + List configurations) { + return new WebApplicationContextRunner(contextFactory, environmentProperties, + systemProperties, classLoader, parent, configurations); + } + /** * Decorate the specified {@code contextFactory} to set a {@link MockServletContext} * on each newly created {@link WebApplicationContext}.