diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 0df2fa53daa..3f2dedee8b1 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -6520,6 +6520,9 @@ example shows a class that uses both `@WebFluxTest` and a `WebTestClient`: } ---- +TIP: This setup is only supported by WebFlux applications as using `WebTestClient` in a +mocked web application only works with WebFlux at the moment. + A list of the auto-configuration that is enabled by `@WebFluxTest` can be <>. diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java index f83789e3041..b0ed1a04d26 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/AutoConfigureWebTestClient.java @@ -29,7 +29,8 @@ import org.springframework.boot.test.autoconfigure.properties.PropertyMapping; import org.springframework.test.web.reactive.server.WebTestClient; /** - * Annotation that can be applied to a test class to enable a {@link WebTestClient}. + * Annotation that can be applied to a test class to enable a {@link WebTestClient}. At + * the moment, only WebFlux applications are supported. * * @author Stephane Nicoll * @since 2.0.0 diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java index b5c1aa763fa..16946190c6b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfiguration.java @@ -22,9 +22,11 @@ import java.util.List; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.codec.CodecCustomizer; @@ -33,6 +35,7 @@ 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; +import org.springframework.web.server.WebHandler; /** * Auto-configuration for {@link WebTestClient}. @@ -43,12 +46,13 @@ import org.springframework.web.reactive.function.client.WebClient; */ @Configuration @ConditionalOnClass({ WebClient.class, WebTestClient.class }) -@AutoConfigureAfter(CodecsAutoConfiguration.class) +@AutoConfigureAfter({ CodecsAutoConfiguration.class, WebFluxAutoConfiguration.class }) @EnableConfigurationProperties public class WebTestClientAutoConfiguration { @Bean @ConditionalOnMissingBean + @ConditionalOnBean(WebHandler.class) public WebTestClient webTestClient(ApplicationContext applicationContext, List customizers) { WebTestClient.Builder builder = WebTestClient diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java index 8cda5379d41..1b653f74fea 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/WebTestClientAutoConfigurationTests.java @@ -18,18 +18,15 @@ package org.springframework.boot.test.autoconfigure.web.reactive; import java.time.Duration; import java.time.temporal.ChronoUnit; -import java.util.Collections; -import org.junit.After; import org.junit.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.web.codec.CodecCustomizer; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; import org.springframework.http.codec.CodecConfigurer; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.reactive.server.WebTestClient; @@ -44,50 +41,43 @@ import static org.mockito.Mockito.verify; * Tests for {@link WebTestClientAutoConfiguration} * * @author Brian Clozel + * @author Stephane Nicoll */ public class WebTestClientAutoConfigurationTests { - private AnnotationConfigApplicationContext context; + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + WebTestClientAutoConfiguration.class)); - @After - public void close() { - if (this.context != null) { - this.context.close(); - } + @Test + public void shouldNotBeConfiguredWithoutWebHandler() { + this.contextRunner.run((context) -> { + assertThat(context).hasNotFailed(); + assertThat(context).doesNotHaveBean(WebTestClient.class); + }); } @Test public void shouldCustomizeClientCodecs() { - load(CodecConfiguration.class); - WebTestClient webTestClient = this.context.getBean(WebTestClient.class); - CodecCustomizer codecCustomizer = this.context.getBean(CodecCustomizer.class); - assertThat(webTestClient).isNotNull(); - verify(codecCustomizer).customize(any(CodecConfigurer.class)); + this.contextRunner.withUserConfiguration(CodecConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(WebTestClient.class); + assertThat(context).hasSingleBean(CodecCustomizer.class); + verify(context.getBean(CodecCustomizer.class)).customize( + any(CodecConfigurer.class)); + }); } @Test public void shouldCustomizeTimeout() { - PropertySource propertySource = new MapPropertySource("test", Collections - .singletonMap("spring.test.webtestclient.timeout", (Object) "PT15M")); - load(propertySource, BaseConfiguration.class); - WebTestClient webTestClient = this.context.getBean(WebTestClient.class); - Object duration = ReflectionTestUtils.getField(webTestClient, "timeout"); - assertThat(duration).isEqualTo(Duration.of(15, ChronoUnit.MINUTES)); - } - - private void load(Class... config) { - load(null, config); - } - - private void load(PropertySource propertySource, Class... config) { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - if (propertySource != null) { - context.getEnvironment().getPropertySources().addFirst(propertySource); - } - context.register(config); - context.register(WebTestClientAutoConfiguration.class); - context.refresh(); - this.context = context; + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .withPropertyValues("spring.test.webtestclient.timeout=15m") + .run((context) -> { + WebTestClient webTestClient = context.getBean(WebTestClient.class); + Object duration = ReflectionTestUtils.getField(webTestClient, + "timeout"); + assertThat(duration).isEqualTo(Duration.of(15, ChronoUnit.MINUTES)); + }); } @Configuration