Support customization of WebTestClient.Builder when using @SpringBootTest

Closes gh-15132
pull/18490/head
Andy Wilkinson 5 years ago
parent 100fc8cf2c
commit 96f85a40de

@ -6052,6 +6052,13 @@ include::{code-examples}/test/web/RandomPortTestRestTemplateExampleTests.java[ta
[[boot-features-testing-spring-boot-applications-customizing-web-test-client]]
==== Customizing WebTestClient
To customize the `WebTestClient` bean, configure a `WebTestClientBuilderCustomizer` bean.
Any such beans are called with the `WebTestClient.Builder` that is used to create the `WebTestClient`.
[[boot-features-testing-spring-boot-applications-jmx]] [[boot-features-testing-spring-boot-applications-jmx]]
==== Using JMX ==== Using JMX
As the test context framework caches context, JMX is disabled by default to prevent identical components to register on the same domain. As the test context framework caches context, JMX is disabled by default to prevent identical components to register on the same domain.

@ -20,6 +20,7 @@ import java.time.Duration;
import java.util.Collection; import java.util.Collection;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer;
import org.springframework.boot.web.codec.CodecCustomizer; import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.http.codec.ClientCodecConfigurer;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;

@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer;
import org.springframework.boot.web.codec.CodecCustomizer; import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;

@ -26,14 +26,12 @@ import org.springframework.test.web.reactive.server.WebTestClient.Builder;
* @author Andy Wilkinson * @author Andy Wilkinson
* @since 2.0.0 * @since 2.0.0
* @see WebTestClientAutoConfiguration * @see WebTestClientAutoConfiguration
* @deprecated since 2.2 in favor of
* {@link org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer}
*/ */
@FunctionalInterface @FunctionalInterface
public interface WebTestClientBuilderCustomizer { @Deprecated
public interface WebTestClientBuilderCustomizer
/** extends org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer {
* Customize the given {@code builder}.
* @param builder the builder
*/
void customize(Builder builder);
} }

@ -0,0 +1,38 @@
/*
* Copyright 2012-2019 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.test.web.reactive.server;
import org.springframework.test.web.reactive.server.WebTestClient.Builder;
/**
* A customizer for a {@link Builder}. Any {@code WebTestClientBuilderCustomizer} beans
* found in the application context will be {@link #customize called} to customize the
* auto-configured {@link Builder}.
*
* @author Andy Wilkinson
* @since 2.2.0
*/
@FunctionalInterface
public interface WebTestClientBuilderCustomizer {
/**
* Customize the given {@code builder}.
* @param builder the builder
*/
void customize(Builder builder);
}

@ -160,6 +160,7 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
String port = this.applicationContext.getEnvironment().getProperty("local.server.port", "8080"); String port = this.applicationContext.getEnvironment().getProperty("local.server.port", "8080");
String baseUrl = (sslEnabled ? "https" : "http") + "://localhost:" + port; String baseUrl = (sslEnabled ? "https" : "http") + "://localhost:" + port;
WebTestClient.Builder builder = WebTestClient.bindToServer(); WebTestClient.Builder builder = WebTestClient.bindToServer();
customizeWebTestClientBuilder(builder, this.applicationContext);
customizeWebTestClientCodecs(builder, this.applicationContext); customizeWebTestClientCodecs(builder, this.applicationContext);
return builder.baseUrl(baseUrl).build(); return builder.baseUrl(baseUrl).build();
} }
@ -175,6 +176,13 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
} }
} }
private void customizeWebTestClientBuilder(WebTestClient.Builder clientBuilder, ApplicationContext context) {
for (WebTestClientBuilderCustomizer customizer : context
.getBeansOfType(WebTestClientBuilderCustomizer.class).values()) {
customizer.customize(clientBuilder);
}
}
private void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder, ApplicationContext context) { private void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder, ApplicationContext context) {
Collection<CodecCustomizer> codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values(); Collection<CodecCustomizer> codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values();
if (!CollectionUtils.isEmpty(codecCustomizers)) { if (!CollectionUtils.isEmpty(codecCustomizers)) {

@ -33,6 +33,11 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient.Builder;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/** /**
* Integration test for {@link WebTestClientContextCustomizer}. * Integration test for {@link WebTestClientContextCustomizer}.
@ -46,8 +51,12 @@ class WebTestClientContextCustomizerIntegrationTests {
@Autowired @Autowired
private WebTestClient webTestClient; private WebTestClient webTestClient;
@Autowired
private WebTestClientBuilderCustomizer clientBuilderCustomizer;
@Test @Test
void test() { void test() {
verify(this.clientBuilderCustomizer).customize(any(Builder.class));
this.webTestClient.get().uri("/").exchange().expectBody(String.class).isEqualTo("hello"); this.webTestClient.get().uri("/").exchange().expectBody(String.class).isEqualTo("hello");
} }
@ -60,6 +69,11 @@ class WebTestClientContextCustomizerIntegrationTests {
return new TomcatReactiveWebServerFactory(0); return new TomcatReactiveWebServerFactory(0);
} }
@Bean
WebTestClientBuilderCustomizer clientBuilderCustomizer() {
return mock(WebTestClientBuilderCustomizer.class);
}
} }
static class TestHandler implements HttpHandler { static class TestHandler implements HttpHandler {

Loading…
Cancel
Save