Commit 16c52bce authored by Andy Wilkinson's avatar Andy Wilkinson

Introduce WebTestClientBuilderCustomizer callback

Closes gh-11579
parent 9b9931e8
/*
* Copyright 2012-2018 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.time.Duration;
import java.util.Collection;
import java.util.function.Consumer;
import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.http.codec.ClientCodecConfigurer;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient.Builder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
/**
* {@link WebTestClientBuilderCustomizer} for a typical Spring Boot application. Usually
* applied automatically via
* {@link AutoConfigureWebTestClient @AutoConfigureWebTestClient}, but may also be used
* directly.
*
* @author Andy Wilkinson
* @since 2.0.0
*/
public class SpringBootWebTestClientBuilderCustomizer
implements WebTestClientBuilderCustomizer {
private final Collection<CodecCustomizer> codecCustomizers;
private Duration timeout;
/**
* Create a new {@code SpringBootWebTestClientBuilderCustomizer} that will configure
* the builder's codecs using the given {@code codecCustomizers}.
* @param codecCustomizers the codec customizers
*/
public SpringBootWebTestClientBuilderCustomizer(
Collection<CodecCustomizer> codecCustomizers) {
this.codecCustomizers = codecCustomizers;
}
public void setTimeout(Duration timeout) {
this.timeout = timeout;
}
@Override
public void customize(Builder builder) {
if (this.timeout != null) {
builder.responseTimeout(this.timeout);
}
customizeWebTestClientCodecs(builder);
}
private void customizeWebTestClientCodecs(WebTestClient.Builder builder) {
if (!CollectionUtils.isEmpty(this.codecCustomizers)) {
builder.exchangeStrategies(ExchangeStrategies.builder()
.codecs(applyCustomizers(this.codecCustomizers)).build());
}
}
private Consumer<ClientCodecConfigurer> applyCustomizers(
Collection<CodecCustomizer> customizers) {
return (codecs) -> customizers
.forEach((customizer) -> customizer.customize(codecs));
}
}
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
......@@ -16,68 +16,55 @@
package org.springframework.boot.test.autoconfigure.web.reactive;
import java.time.Duration;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.ObjectProvider;
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.context.properties.bind.Binder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.http.codec.ClientCodecConfigurer;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient.Builder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
/**
* Auto-configuration for {@link WebTestClient}.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
* @since 2.0.0
*/
@Configuration
@ConditionalOnClass({ WebClient.class, WebTestClient.class })
@AutoConfigureAfter(CodecsAutoConfiguration.class)
@EnableConfigurationProperties
public class WebTestClientAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public WebTestClient webTestClient(ApplicationContext applicationContext) {
public WebTestClient webTestClient(ApplicationContext applicationContext,
List<WebTestClientBuilderCustomizer> customizers) {
WebTestClient.Builder builder = WebTestClient
.bindToApplicationContext(applicationContext).configureClient();
customizeWebTestClient(builder, applicationContext);
customizeWebTestClientCodecs(builder, applicationContext);
return builder.build();
}
private void customizeWebTestClient(Builder builder,
ApplicationContext applicationContext) {
Binder.get(applicationContext.getEnvironment())
.bind("spring.test.webtestclient.timeout", Duration.class)
.ifBound(builder::responseTimeout);
}
private void customizeWebTestClientCodecs(WebTestClient.Builder builder,
ApplicationContext applicationContext) {
Collection<CodecCustomizer> customizers = applicationContext
.getBeansOfType(CodecCustomizer.class).values();
if (!CollectionUtils.isEmpty(customizers)) {
builder.exchangeStrategies(ExchangeStrategies.builder()
.codecs(applyCustomizers(customizers)).build());
for (WebTestClientBuilderCustomizer customizer : customizers) {
customizer.customize(builder);
}
return builder.build();
}
private Consumer<ClientCodecConfigurer> applyCustomizers(
Collection<CodecCustomizer> customizers) {
return (codecs) -> customizers
.forEach((customizer) -> customizer.customize(codecs));
@Bean
@ConfigurationProperties(prefix = "spring.test.webtestclient")
public SpringBootWebTestClientBuilderCustomizer springBootWebTestClientBuilderCustomizer(
ObjectProvider<Collection<CodecCustomizer>> codecCustomizers) {
return new SpringBootWebTestClientBuilderCustomizer(
codecCustomizers.getIfAvailable(Collections::emptyList));
}
}
/*
* Copyright 2012-2018 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.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.0.0
* @see WebTestClientAutoConfiguration
*/
@FunctionalInterface
public interface WebTestClientBuilderCustomizer {
/**
* Customize the given {@code builder}.
* @param builder the builder
*/
void customize(Builder builder);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment