org.springframework.data
spring-data-jpa
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebFlux.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebFlux.java
new file mode 100644
index 0000000000..00ec09dd21
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebFlux.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+
+/**
+ * {@link ImportAutoConfiguration Auto-configuration imports} for typical Spring WebFlux
+ * tests. Most tests should consider using {@link WebFluxTest @WebFluxTest} rather than
+ * using this annotation directly.
+ *
+ * @author Stephane Nicoll
+ * @since 2.0.0
+ * @see WebFluxTest
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@ImportAutoConfiguration
+public @interface AutoConfigureWebFlux {
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java
new file mode 100644
index 0000000000..e92520419b
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * Annotation that can be applied to a test class to enable a {@link WebTestClient}.
+ *
+ * @author Stephane Nicoll
+ * @since 2.0.0
+ * @see WebTestClientAutoConfiguration
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@ImportAutoConfiguration
+public @interface AutoConfigureWebTestClient {
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java
new file mode 100644
index 0000000000..9fa551eb1f
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
+import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.test.context.BootstrapWith;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)}
+ * for a typical Spring WebFlux test. Can be used when a test focuses
+ * only on Spring WebFlux components.
+ *
+ * Using this annotation will disable full auto-configuration and instead apply only
+ * configuration relevant to WebFlux tests (i.e. {@code @Controller},
+ * {@code @ControllerAdvice}, {@code @JsonComponent} and {@code WebFluxConfigurer} beans
+ * but not {@code @Component}, {@code @Service} or {@code @Repository} beans).
+ *
+ * By default, tests annotated with {@code @WebFluxTest} will also auto-configure a
+ * {@link WebTestClient}. For more fine-grained control of WebTestClient the
+ * {@link AutoConfigureWebTestClient @AutoConfigureWebTestClient} annotation can be used.
+ *
+ * Typically {@code @WebFluxTest} is used in combination with {@link MockBean @MockBean} or
+ * {@link Import @Import} to create any collaborators required by your {@code @Controller}
+ * beans.
+ *
+ * If you are looking to load your full application configuration and use WebTestClient,
+ * you should consider {@link SpringBootTest @SpringBootTest} combined with
+ * {@link AutoConfigureWebTestClient @AutoConfigureWebTestClient} rather than this
+ * annotation.
+ *
+ * @author Stephane Nicoll
+ * @since 2.0.0
+ * @see AutoConfigureWebFlux
+ * @see AutoConfigureWebTestClient
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@BootstrapWith(WebFluxTestContextBootstrapper.class)
+@OverrideAutoConfiguration(enabled = false)
+@TypeExcludeFilters(WebFluxTypeExcludeFilter.class)
+@AutoConfigureCache
+@AutoConfigureWebFlux
+@AutoConfigureWebTestClient
+@ImportAutoConfiguration
+public @interface WebFluxTest {
+
+ /**
+ * Specifies the controllers to test. This is an alias of {@link #controllers()} which
+ * can be used for brevity if no other attributes are defined. See
+ * {@link #controllers()} for details.
+ * @see #controllers()
+ * @return the controllers to test
+ */
+ @AliasFor("controllers")
+ Class>[] value() default {};
+
+ /**
+ * Specifies the controllers to test. May be left blank if all {@code @Controller}
+ * beans should be added to the application context.
+ * @see #value()
+ * @return the controllers to test
+ */
+ @AliasFor("value")
+ Class>[] controllers() default {};
+
+ /**
+ * Determines if default filtering should be used with
+ * {@link SpringBootApplication @SpringBootApplication}. By default only
+ * {@code @Controller} (when no explicit {@link #controllers() controllers} are
+ * defined), {@code @ControllerAdvice} and {@code WebFluxConfigurer} beans are
+ * included.
+ * @see #includeFilters()
+ * @see #excludeFilters()
+ * @return if default filters should be used
+ */
+ boolean useDefaultFilters() default true;
+
+ /**
+ * A set of include filters which can be used to add otherwise filtered beans to the
+ * application context.
+ * @return include filters to apply
+ */
+ ComponentScan.Filter[] includeFilters() default {};
+
+ /**
+ * A set of exclude filters which can be used to filter beans that would otherwise be
+ * added to the application context.
+ * @return exclude filters to apply
+ */
+ ComponentScan.Filter[] excludeFilters() default {};
+
+ /**
+ * Auto-configuration exclusions that should be applied for this test.
+ * @return auto-configuration exclusions to apply
+ */
+ @AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
+ Class>[] excludeAutoConfiguration() default {};
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java
new file mode 100644
index 0000000000..95f44f5877
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestContextBootstrapper.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.springframework.boot.test.context.ReactiveWebMergedContextConfiguration;
+import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
+import org.springframework.test.context.MergedContextConfiguration;
+import org.springframework.test.context.TestContextBootstrapper;
+
+/**
+ * {@link TestContextBootstrapper} for {@link WebFluxTest @WebFluxTest} support.
+ *
+ * @author Stephane Nicoll
+ */
+class WebFluxTestContextBootstrapper extends SpringBootTestContextBootstrapper {
+
+ @Override
+ protected MergedContextConfiguration processMergedContextConfiguration(
+ MergedContextConfiguration mergedConfig) {
+ return new ReactiveWebMergedContextConfiguration(
+ super.processMergedContextConfiguration(mergedConfig));
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java
new file mode 100644
index 0000000000..d709654f64
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.springframework.boot.context.TypeExcludeFilter;
+import org.springframework.boot.jackson.JsonComponent;
+import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.reactive.config.WebFluxConfigurer;
+
+/**
+ * {@link TypeExcludeFilter} for {@link WebFluxTest @WebFluxTest}.
+ *
+ * @author Stephane Nicoll
+ */
+class WebFluxTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
+
+ private static final Set> DEFAULT_INCLUDES;
+
+ static {
+ Set> includes = new LinkedHashSet>();
+ includes.add(ControllerAdvice.class);
+ includes.add(JsonComponent.class);
+ includes.add(WebFluxConfigurer.class);
+ DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
+ }
+
+ private static final Set> DEFAULT_INCLUDES_AND_CONTROLLER;
+
+ static {
+ Set> includes = new LinkedHashSet>(DEFAULT_INCLUDES);
+ includes.add(Controller.class);
+ DEFAULT_INCLUDES_AND_CONTROLLER = Collections.unmodifiableSet(includes);
+ }
+
+ private final WebFluxTest annotation;
+
+ WebFluxTypeExcludeFilter(Class> testClass) {
+ this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
+ WebFluxTest.class);
+ }
+
+ @Override
+ protected boolean hasAnnotation() {
+ return this.annotation != null;
+ }
+
+ @Override
+ protected ComponentScan.Filter[] getFilters(FilterType type) {
+ switch (type) {
+ case INCLUDE:
+ return this.annotation.includeFilters();
+ case EXCLUDE:
+ return this.annotation.excludeFilters();
+ }
+ throw new IllegalStateException("Unsupported type " + type);
+ }
+
+ @Override
+ protected boolean isUseDefaultFilters() {
+ return this.annotation.useDefaultFilters();
+ }
+
+ @Override
+ protected Set> getDefaultIncludes() {
+ if (ObjectUtils.isEmpty(this.annotation.controllers())) {
+ return DEFAULT_INCLUDES_AND_CONTROLLER;
+ }
+ return DEFAULT_INCLUDES;
+ }
+
+ @Override
+ protected Set> getComponentIncludes() {
+ return new LinkedHashSet<>(Arrays.asList(this.annotation.controllers()));
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java
new file mode 100644
index 0000000000..4ed754af2a
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.web.reactive.server.WebTestClient;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * Auto-configuration for {@link WebTestClient}.
+ *
+ * @author Stephane Nicoll
+ */
+@Configuration
+@ConditionalOnClass({ WebClient.class, WebTestClient.class })
+public class WebTestClientAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public WebTestClient webTestClient(ApplicationContext applicationContext) {
+ return WebTestClient.bindToApplicationContext(applicationContext).build();
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories
index 8580a29555..49a34df215 100644
--- a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -46,6 +46,16 @@ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters=\
org.springframework.boot.test.autoconfigure.json.JsonTestersAutoConfiguration
+# AutoConfigureWebClient auto-configuration imports
+org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient=\
+org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration
+
+# AutoConfigureWebFlux auto-configuration imports
+org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux=\
+org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
+org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
+org.springframework.boot.autoconfigure.webflux.WebFluxAnnotationAutoConfiguration
+
# AutoConfigureMockMvc auto-configuration imports
org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc=\
org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration,\
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleController1.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleController1.java
new file mode 100644
index 0000000000..9e13e6f086
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleController1.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import reactor.core.publisher.Mono;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Example {@link Controller} used with {@link WebFluxTest} tests.
+ *
+ * @author Stephane Nicoll
+ */
+@RestController
+public class ExampleController1 {
+
+ @GetMapping("/one")
+ public Mono one() {
+ return Mono.just("one");
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleController2.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleController2.java
new file mode 100644
index 0000000000..6ada238356
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleController2.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import reactor.core.publisher.Mono;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Example {@link Controller} used with {@link WebFluxTest} tests.
+ *
+ * @author Stephane Nicoll
+ */
+@RestController
+public class ExampleController2 {
+
+ @GetMapping("/two")
+ public Mono two() {
+ return Mono.just("two");
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleRealService.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleRealService.java
new file mode 100644
index 0000000000..d9f3da538c
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleRealService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.springframework.stereotype.Service;
+
+/**
+ * Example {@link Service} used with {@link WebFluxTest} tests.
+ *
+ * @author Stephane Nicoll
+ */
+@Service
+public class ExampleRealService {
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleWebFluxApplication.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleWebFluxApplication.java
new file mode 100644
index 0000000000..f0dcb5097f
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/ExampleWebFluxApplication.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Example {@link SpringBootApplication} used with {@link WebFluxTest} tests.
+ *
+ * @author Stephane Nicoll
+ */
+@SpringBootApplication
+public class ExampleWebFluxApplication {
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestAllControllersIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestAllControllersIntegrationTests.java
new file mode 100644
index 0000000000..35fa06ab7c
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestAllControllersIntegrationTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * Tests for {@link WebFluxTest} when no explicit controller is defined.
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@WebFluxTest
+public class WebFluxTestAllControllersIntegrationTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @Test
+ public void shouldFindController1() {
+ this.webClient
+ .get().uri("/one")
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value().isEqualTo("one");
+ }
+
+ @Test
+ public void shouldFindController2() {
+ this.webClient
+ .get().uri("/two")
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value().isEqualTo("two");
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestAutoConfigurationIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestAutoConfigurationIntegrationTests.java
new file mode 100644
index 0000000000..068492526e
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestAutoConfigurationIntegrationTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.importedAutoConfiguration;
+
+/**
+ * Tests for the auto-configuration imported by {@link WebFluxTest}.
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@WebFluxTest
+public class WebFluxTestAutoConfigurationIntegrationTests {
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Test
+ public void messageSourceAutoConfigurationIsImported() {
+ assertThat(this.applicationContext)
+ .has(importedAutoConfiguration(MessageSourceAutoConfiguration.class));
+ }
+
+ @Test
+ public void validationAutoConfigurationIsImported() {
+ assertThat(this.applicationContext)
+ .has(importedAutoConfiguration(ValidationAutoConfiguration.class));
+ }
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestMessageSourceIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestMessageSourceIntegrationTests.java
new file mode 100644
index 0000000000..0ad72688af
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestMessageSourceIntegrationTests.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import java.util.Locale;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.MessageSource;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link WebFluxTest} and {@link MessageSource} auto-configuration.
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@WebFluxTest
+@TestPropertySource(properties = "spring.messages.basename=web-test-messages")
+public class WebFluxTestMessageSourceIntegrationTests {
+
+ @Autowired
+ private ApplicationContext context;
+
+ @Test
+ public void messageSourceHasBeenAutoConfigured() {
+ assertThat(this.context.getMessage("a", null, Locale.ENGLISH)).isEqualTo("alpha");
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestOneControllerIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestOneControllerIntegrationTests.java
new file mode 100644
index 0000000000..e152ab4ba6
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTestOneControllerIntegrationTests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * Tests for {@link WebFluxTest} when a specific controller is defined.
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@WebFluxTest(controllers = ExampleController1.class)
+public class WebFluxTestOneControllerIntegrationTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @Test
+ public void shouldFindController() {
+ this.webClient
+ .get().uri("/one")
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value().isEqualTo("one");
+ }
+
+ @Test
+ public void shouldNotScanOtherController() {
+ this.webClient
+ .get().uri("/two")
+ .exchange()
+ .expectStatus().isNotFound();
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilterTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilterTests.java
new file mode 100644
index 0000000000..f3ab2b13ad
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilterTests.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.stereotype.Repository;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.reactive.config.WebFluxConfigurer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link WebFluxTypeExcludeFilter}.
+ *
+ * @author Phillip Webb
+ * @author Stephane Nicoll
+ */
+public class WebFluxTypeExcludeFilterTests {
+
+ private MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
+
+ @Test
+ public void matchWhenHasNoControllers() throws Exception {
+ WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
+ WithNoControllers.class);
+ assertThat(excludes(filter, Controller1.class)).isFalse();
+ assertThat(excludes(filter, Controller2.class)).isFalse();
+ assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
+ assertThat(excludes(filter, ExampleWeb.class)).isFalse();
+ assertThat(excludes(filter, ExampleService.class)).isTrue();
+ assertThat(excludes(filter, ExampleRepository.class)).isTrue();
+ }
+
+ @Test
+ public void matchWhenHasController() throws Exception {
+ WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
+ WithController.class);
+ assertThat(excludes(filter, Controller1.class)).isFalse();
+ assertThat(excludes(filter, Controller2.class)).isTrue();
+ assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
+ assertThat(excludes(filter, ExampleWeb.class)).isFalse();
+ assertThat(excludes(filter, ExampleService.class)).isTrue();
+ assertThat(excludes(filter, ExampleRepository.class)).isTrue();
+ }
+
+ @Test
+ public void matchNotUsingDefaultFilters() throws Exception {
+ WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
+ NotUsingDefaultFilters.class);
+ assertThat(excludes(filter, Controller1.class)).isTrue();
+ assertThat(excludes(filter, Controller2.class)).isTrue();
+ assertThat(excludes(filter, ExampleControllerAdvice.class)).isTrue();
+ assertThat(excludes(filter, ExampleWeb.class)).isTrue();
+ assertThat(excludes(filter, ExampleService.class)).isTrue();
+ assertThat(excludes(filter, ExampleRepository.class)).isTrue();
+ }
+
+ @Test
+ public void matchWithIncludeFilter() throws Exception {
+ WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
+ WithIncludeFilter.class);
+ assertThat(excludes(filter, Controller1.class)).isFalse();
+ assertThat(excludes(filter, Controller2.class)).isFalse();
+ assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
+ assertThat(excludes(filter, ExampleWeb.class)).isFalse();
+ assertThat(excludes(filter, ExampleService.class)).isTrue();
+ assertThat(excludes(filter, ExampleRepository.class)).isFalse();
+ }
+
+ @Test
+ public void matchWithExcludeFilter() throws Exception {
+ WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
+ WithExcludeFilter.class);
+ assertThat(excludes(filter, Controller1.class)).isTrue();
+ assertThat(excludes(filter, Controller2.class)).isFalse();
+ assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
+ assertThat(excludes(filter, ExampleWeb.class)).isFalse();
+ assertThat(excludes(filter, ExampleService.class)).isTrue();
+ assertThat(excludes(filter, ExampleRepository.class)).isTrue();
+ }
+
+ private boolean excludes(WebFluxTypeExcludeFilter filter, Class> type)
+ throws IOException {
+ MetadataReader metadataReader = this.metadataReaderFactory
+ .getMetadataReader(type.getName());
+ return filter.match(metadataReader, this.metadataReaderFactory);
+ }
+
+ @WebFluxTest
+ static class WithNoControllers {
+
+ }
+
+ @WebFluxTest(Controller1.class)
+ static class WithController {
+
+ }
+
+ @WebFluxTest(useDefaultFilters = false)
+ static class NotUsingDefaultFilters {
+
+ }
+
+ @WebFluxTest(includeFilters = @Filter(Repository.class))
+ static class WithIncludeFilter {
+
+ }
+
+ @WebFluxTest(excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Controller1.class))
+ static class WithExcludeFilter {
+
+ }
+
+ @Controller
+ static class Controller1 {
+
+ }
+
+ @Controller
+ static class Controller2 {
+
+ }
+
+ @ControllerAdvice
+ static class ExampleControllerAdvice {
+
+ }
+
+ static class ExampleWeb implements WebFluxConfigurer {
+
+ }
+
+ @Service
+ static class ExampleService {
+
+ }
+
+ @Repository
+ static class ExampleRepository {
+
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientSpringBootTestIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientSpringBootTestIntegrationTests.java
new file mode 100644
index 0000000000..d34ab379a9
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientSpringBootTestIntegrationTests.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link SpringBootTest} with {@link AutoConfigureWebTestClient} (i.e. full
+ * integration test).
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(properties = "spring.main.web-application-type=reactive")
+@AutoConfigureWebTestClient
+public class WebTestClientSpringBootTestIntegrationTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Test
+ public void shouldFindController1() {
+ this.webClient
+ .get().uri("/one")
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value().isEqualTo("one");
+ }
+
+ @Test
+ public void shouldFindController2() {
+ this.webClient
+ .get().uri("/two")
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody(String.class).value().isEqualTo("two");
+ }
+
+ @Test
+ public void shouldHaveRealService() throws Exception {
+ assertThat(this.applicationContext.getBeansOfType(ExampleRealService.class))
+ .hasSize(1);
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestMessageSourceIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestMessageSourceIntegrationTests.java
index 007e2abb1c..7207a989e6 100644
--- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestMessageSourceIntegrationTests.java
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestMessageSourceIntegrationTests.java
@@ -36,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@WebMvcTest(secure = false)
-@TestPropertySource(properties = "spring.messages.basename=web-mvc-test-messages")
+@TestPropertySource(properties = "spring.messages.basename=web-test-messages")
public class WebMvcTestMessageSourceIntegrationTests {
@Autowired
diff --git a/spring-boot-test-autoconfigure/src/test/resources/web-mvc-test-messages.properties b/spring-boot-test-autoconfigure/src/test/resources/web-mvc-test-messages.properties
deleted file mode 100644
index d420f4482d..0000000000
--- a/spring-boot-test-autoconfigure/src/test/resources/web-mvc-test-messages.properties
+++ /dev/null
@@ -1 +0,0 @@
-a: alpha
diff --git a/spring-boot-test-autoconfigure/src/test/resources/web-test-messages.properties b/spring-boot-test-autoconfigure/src/test/resources/web-test-messages.properties
new file mode 100644
index 0000000000..2291e29f1f
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/resources/web-test-messages.properties
@@ -0,0 +1 @@
+a=alpha
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebMergedContextConfiguration.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebMergedContextConfiguration.java
index d2c9b29c2e..01d6da0fad 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebMergedContextConfiguration.java
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebMergedContextConfiguration.java
@@ -23,10 +23,11 @@ import org.springframework.test.context.MergedContextConfiguration;
* all of its superclasses for a reactive web application.
*
* @author Stephane Nicoll
+ * @since 2.0.0
*/
-class ReactiveWebMergedContextConfiguration extends MergedContextConfiguration {
+public class ReactiveWebMergedContextConfiguration extends MergedContextConfiguration {
- ReactiveWebMergedContextConfiguration(
+ public ReactiveWebMergedContextConfiguration(
MergedContextConfiguration mergedConfig) {
super(mergedConfig);
}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java
index 2958cff33a..8f3ee51196 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java
@@ -28,6 +28,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.bind.RelaxedPropertyResolver;
+import org.springframework.boot.context.GenericReactiveWebApplicationContext;
import org.springframework.boot.test.mock.web.SpringBootMockServletContext;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.support.ServletContextApplicationContextInitializer;
@@ -116,6 +117,9 @@ public class SpringBootContextLoader extends AbstractContextLoader {
}
else if (config instanceof ReactiveWebMergedContextConfiguration) {
application.setWebApplicationType(WebApplicationType.REACTIVE);
+ if (!isEmbeddedWebEnvironment(config)) {
+ new ReactiveWebConfigurer().configure(application);
+ }
}
else {
application.setWebApplicationType(WebApplicationType.NONE);
@@ -281,6 +285,19 @@ public class SpringBootContextLoader extends AbstractContextLoader {
}
+ /**
+ * Inner class to configure {@link ReactiveWebMergedContextConfiguration}.
+ */
+ private static class ReactiveWebConfigurer {
+
+ private static final Class WEB_CONTEXT_CLASS = GenericReactiveWebApplicationContext.class;
+
+ void configure(SpringApplication application) {
+ application.setApplicationContextClass(WEB_CONTEXT_CLASS);
+ }
+
+ }
+
/**
* Adapts a {@link ContextCustomizer} to a {@link ApplicationContextInitializer} so
* that it can be triggered via {@link SpringApplication}.
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java
index 111241f4ca..b81d8c68f8 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java
@@ -164,8 +164,8 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
mergedConfig = new WebMergedContextConfiguration(mergedConfig,
resourceBasePath);
}
- else if (webApplicationType == WebApplicationType.REACTIVE
- && webEnvironment.isEmbedded()) {
+ else if (webApplicationType == WebApplicationType.REACTIVE &&
+ (webEnvironment.isEmbedded() || webEnvironment == WebEnvironment.MOCK)) {
return new ReactiveWebMergedContextConfiguration(mergedConfig);
}
}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java
index 5ec524e376..0711fc6dab 100644
--- a/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractSpringBootTestEmbeddedReactiveWebEnvironmentTests.java
@@ -21,8 +21,8 @@ import reactor.core.publisher.Mono;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.ReactiveWebApplicationContext;
import org.springframework.boot.context.embedded.LocalServerPort;
-import org.springframework.boot.context.embedded.ReactiveWebApplicationContext;
import org.springframework.boot.context.embedded.ReactiveWebServerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatReactiveWebServerFactory;
import org.springframework.context.ApplicationContext;
diff --git a/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java
index 5777694b28..785d5aacb4 100644
--- a/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java
+++ b/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java
@@ -182,7 +182,7 @@ public class SpringApplication {
* reactive web environments.
*/
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
- + "boot.context.embedded.ReactiveWebApplicationContext";
+ + "boot.context.embedded.EmbeddedReactiveWebApplicationContext";
private static final String REACTIVE_WEB_ENVIRONMENT_CLASS = "org.springframework."
+ "web.reactive.DispatcherHandler";
diff --git a/spring-boot/src/main/java/org/springframework/boot/context/GenericReactiveWebApplicationContext.java b/spring-boot/src/main/java/org/springframework/boot/context/GenericReactiveWebApplicationContext.java
new file mode 100644
index 0000000000..52f5b44cbc
--- /dev/null
+++ b/spring-boot/src/main/java/org/springframework/boot/context/GenericReactiveWebApplicationContext.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.context;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+/**
+ * Subclass of {@link AnnotationConfigApplicationContext}, suitable for reactive web
+ * environments.
+ *
+ * @author Stephane Nicoll
+ * @since 2.0.0
+ */
+public class GenericReactiveWebApplicationContext
+ extends AnnotationConfigApplicationContext
+ implements ReactiveWebApplicationContext {
+
+ public GenericReactiveWebApplicationContext() {
+ super();
+ }
+
+ public GenericReactiveWebApplicationContext(Class>[] annotatedClasses) {
+ super(annotatedClasses);
+ }
+
+}
diff --git a/spring-boot/src/main/java/org/springframework/boot/context/ReactiveWebApplicationContext.java b/spring-boot/src/main/java/org/springframework/boot/context/ReactiveWebApplicationContext.java
new file mode 100644
index 0000000000..7ea904b92f
--- /dev/null
+++ b/spring-boot/src/main/java/org/springframework/boot/context/ReactiveWebApplicationContext.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.context;
+
+import org.springframework.context.ApplicationContext;
+
+/**
+ * Interface to provide configuration for a reactive web application.
+ *
+ * @author Stephane Nicoll
+ * @since 2.0.0
+ */
+public interface ReactiveWebApplicationContext extends ApplicationContext {
+
+}
diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/ReactiveWebApplicationContext.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebApplicationContext.java
similarity index 92%
rename from spring-boot/src/main/java/org/springframework/boot/context/embedded/ReactiveWebApplicationContext.java
rename to spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebApplicationContext.java
index ff28f947d3..4c3be617be 100644
--- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/ReactiveWebApplicationContext.java
+++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebApplicationContext.java
@@ -17,27 +17,28 @@
package org.springframework.boot.context.embedded;
import org.springframework.beans.BeansException;
+import org.springframework.boot.context.GenericReactiveWebApplicationContext;
import org.springframework.context.ApplicationContextException;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.util.StringUtils;
/**
- * A {@link AnnotationConfigApplicationContext} that can be used to bootstrap
+ * A {@link GenericReactiveWebApplicationContext} that can be used to bootstrap
* itself from a contained embedded web server factory bean.
*
* @author Brian Clozel
* @since 2.0.0
*/
-public class ReactiveWebApplicationContext extends AnnotationConfigApplicationContext {
+public class EmbeddedReactiveWebApplicationContext
+ extends GenericReactiveWebApplicationContext {
private volatile EmbeddedWebServer embeddedWebServer;
- public ReactiveWebApplicationContext() {
+ public EmbeddedReactiveWebApplicationContext() {
super();
}
- public ReactiveWebApplicationContext(Class... annotatedClasses) {
+ public EmbeddedReactiveWebApplicationContext(Class... annotatedClasses) {
super(annotatedClasses);
}
diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebServerInitializedEvent.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebServerInitializedEvent.java
index 2ecc85340d..be875318c1 100644
--- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebServerInitializedEvent.java
+++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/EmbeddedReactiveWebServerInitializedEvent.java
@@ -17,7 +17,7 @@
package org.springframework.boot.context.embedded;
/**
- * Event to be published after the {@link ReactiveWebApplicationContext} is
+ * Event to be published after the {@link EmbeddedReactiveWebApplicationContext} is
* refreshed and the {@link EmbeddedWebServer} is ready. Useful for
* obtaining the local port of a running server.
*
@@ -27,17 +27,17 @@ package org.springframework.boot.context.embedded;
*/
public class EmbeddedReactiveWebServerInitializedEvent extends EmbeddedWebServerInitializedEvent {
- private final ReactiveWebApplicationContext applicationContext;
+ private final EmbeddedReactiveWebApplicationContext applicationContext;
public EmbeddedReactiveWebServerInitializedEvent(
EmbeddedWebServer source,
- ReactiveWebApplicationContext applicationContext) {
+ EmbeddedReactiveWebApplicationContext applicationContext) {
super(source);
this.applicationContext = applicationContext;
}
@Override
- public ReactiveWebApplicationContext getApplicationContext() {
+ public EmbeddedReactiveWebApplicationContext getApplicationContext() {
return this.applicationContext;
}
diff --git a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java
index f0db5d0769..3f1d4ba8ed 100644
--- a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java
+++ b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java
@@ -44,7 +44,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
-import org.springframework.boot.context.embedded.ReactiveWebApplicationContext;
+import org.springframework.boot.context.embedded.EmbeddedReactiveWebApplicationContext;
import org.springframework.boot.context.embedded.reactor.ReactorNettyReactiveWebServerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
@@ -406,7 +406,7 @@ public class SpringApplicationTests {
SpringApplication application = new SpringApplication(ExampleReactiveWebConfig.class);
application.setWebApplicationType(WebApplicationType.REACTIVE);
this.context = application.run();
- assertThat(this.context).isInstanceOf(ReactiveWebApplicationContext.class);
+ assertThat(this.context).isInstanceOf(EmbeddedReactiveWebApplicationContext.class);
}
@Test