Auto-configure codecs in WebTestClient
This commit applies what's been done in gh-9166 for WebFlux client and server, but for the `WebTestClient` auto-configuration. `WebTestClient` can be configured for mock or integration tests and this change applies `CodecCustomizer` beans to the client being built. Closes gh-9577
This commit is contained in:
parent
64777204d8
commit
f2e77e46cd
|
@ -16,12 +16,19 @@
|
|||
|
||||
package org.springframework.boot.test.autoconfigure.web.reactive;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
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.web.codec.CodecCustomizer;
|
||||
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.util.CollectionUtils;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
|
@ -31,13 +38,32 @@ import org.springframework.web.reactive.function.client.WebClient;
|
|||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ WebClient.class, WebTestClient.class })
|
||||
@ConditionalOnClass({WebClient.class, WebTestClient.class})
|
||||
@AutoConfigureAfter(CodecsAutoConfiguration.class)
|
||||
public class WebTestClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WebTestClient webTestClient(ApplicationContext applicationContext) {
|
||||
return WebTestClient.bindToApplicationContext(applicationContext).build();
|
||||
|
||||
WebTestClient.Builder clientBuilder = WebTestClient
|
||||
.bindToApplicationContext(applicationContext).configureClient();
|
||||
customizeWebTestClientCodecs(clientBuilder, applicationContext);
|
||||
return clientBuilder.build();
|
||||
}
|
||||
|
||||
private void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder,
|
||||
ApplicationContext applicationContext) {
|
||||
|
||||
Collection<CodecCustomizer> codecCustomizers = applicationContext
|
||||
.getBeansOfType(CodecCustomizer.class).values();
|
||||
if (!CollectionUtils.isEmpty(codecCustomizers)) {
|
||||
clientBuilder.exchangeStrategies(ExchangeStrategies.builder()
|
||||
.codecs(codecs -> {
|
||||
codecCustomizers.forEach(codecCustomizer -> codecCustomizer.customize(codecs));
|
||||
})
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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.After;
|
||||
import org.junit.Test;
|
||||
|
||||
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.http.codec.CodecConfigurer;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.server.WebHandler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebTestClientAutoConfiguration}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class WebTestClientAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCustomizeClientCodecs() throws Exception {
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
private void load(Class<?>... config) {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(config);
|
||||
ctx.register(WebTestClientAutoConfiguration.class);
|
||||
ctx.refresh();
|
||||
this.context = ctx;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
public WebHandler webHandler() {
|
||||
return mock(WebHandler.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(BaseConfiguration.class)
|
||||
static class CodecConfiguration {
|
||||
|
||||
@Bean
|
||||
public CodecCustomizer myCodecCustomizer() {
|
||||
return mock(CodecCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -105,6 +105,11 @@
|
|||
<artifactId>spring-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
|
@ -162,11 +167,6 @@
|
|||
<artifactId>spring-webmvc</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.boot.test.web.reactive;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
@ -23,6 +25,7 @@ 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.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.codec.CodecCustomizer;
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
@ -31,6 +34,8 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
|
|||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
|
||||
/**
|
||||
* {@link ContextCustomizer} for {@link WebTestClient}.
|
||||
|
@ -115,7 +120,9 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
|
|||
String port = this.applicationContext.getEnvironment()
|
||||
.getProperty("local.server.port", "8080");
|
||||
String baseUrl = (sslEnabled ? "https" : "http") + "://localhost:" + port;
|
||||
return WebTestClient.bindToServer().baseUrl(baseUrl).build();
|
||||
WebTestClient.Builder builder = WebTestClient.bindToServer();
|
||||
customizeWebTestClientCodecs(builder, this.applicationContext);
|
||||
return builder.baseUrl(baseUrl).build();
|
||||
}
|
||||
|
||||
private boolean isSslEnabled(ApplicationContext context) {
|
||||
|
@ -130,6 +137,18 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
|
|||
}
|
||||
}
|
||||
|
||||
private void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder,
|
||||
ApplicationContext context) {
|
||||
Collection<CodecCustomizer> codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values();
|
||||
if (!CollectionUtils.isEmpty(codecCustomizers)) {
|
||||
clientBuilder.exchangeStrategies(ExchangeStrategies.builder()
|
||||
.codecs(codecs -> {
|
||||
codecCustomizers.forEach(codecCustomizer -> codecCustomizer.customize(codecs));
|
||||
})
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue