Allow custom WebTestClient beans

Update `@SpringBootTest` `WebTestClient` support so that the bean
definition is only registered when the user has not defined or
auto-configured their own.

See gh-10556
This commit is contained in:
Phillip Webb
2018-01-24 23:24:13 -08:00
parent 177281a504
commit b7c52da457
8 changed files with 304 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -57,8 +57,9 @@ import org.springframework.web.context.WebApplicationContext;
* {@link WebEnvironment#DEFINED_PORT defined} or {@link WebEnvironment#RANDOM_PORT
* random} port.</li>
* <li>Registers a {@link org.springframework.boot.test.web.client.TestRestTemplate
* TestRestTemplate} bean for use in web tests that are using a fully running web server.
* </li>
* TestRestTemplate} and/or
* {@link org.springframework.test.web.reactive.server.WebTestClient WebTestClient} bean
* for use in web tests that are using a fully running web server.</li>
* </ul>
*
* @author Phillip Webb

View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -14,15 +14,21 @@
* limitations under the License.
*/
package org.springframework.boot.test.web.reactive;
package org.springframework.boot.test.web.reactive.server;
import java.util.Collection;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.codec.CodecCustomizer;
@@ -30,6 +36,8 @@ import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFac
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
@@ -63,8 +71,11 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
private void registerWebTestClient(ConfigurableApplicationContext context,
BeanDefinitionRegistry registry) {
registry.registerBeanDefinition(WebTestClient.class.getName(),
new RootBeanDefinition(WebTestClientFactory.class));
RootBeanDefinition definition = new RootBeanDefinition(
WebTestClientRegistrar.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(WebTestClientRegistrar.class.getName(),
definition);
}
@Override
@@ -77,6 +88,45 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
return (obj != null && obj.getClass() == getClass());
}
/**
* {@link BeanDefinitionRegistryPostProcessor} that runs after the
* {@link ConfigurationClassPostProcessor} and add a {@link WebTestClientFactory} bean
* definition when a {@link WebTestClient} hasn't already been registered.
*/
private static class WebTestClientRegistrar
implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) this.beanFactory,
WebTestClient.class).length == 0) {
registry.registerBeanDefinition(WebTestClient.class.getName(),
new RootBeanDefinition(WebTestClientFactory.class));
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
}
}
/**
* {@link FactoryBean} used to create and configure a {@link WebTestClient}.
*/

View File

@@ -1,5 +1,5 @@
/*
* 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.test.web.reactive;
package org.springframework.boot.test.web.reactive.server;
import java.util.List;
@@ -30,7 +30,7 @@ import org.springframework.util.ClassUtils;
*
* @author Stephane Nicoll
*/
public class WebTestClientContextCustomizerFactory implements ContextCustomizerFactory {
class WebTestClientContextCustomizerFactory implements ContextCustomizerFactory {
private static final String WEB_TEST_CLIENT_CLASS = "org.springframework.web.reactive.function.client.WebClient";

View File

@@ -0,0 +1,21 @@
/*
* 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.
*/
/**
* Spring Boot support for testing Spring WebFlux server endpoints via
* {@link org.springframework.test.web.reactive.server.WebTestClient}.
*/
package org.springframework.boot.test.web.reactive.server;

View File

@@ -5,7 +5,7 @@ org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFacto
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory,\
org.springframework.boot.test.web.client.TestRestTemplateTestContextCustomizerFactory,\
org.springframework.boot.test.web.reactive.WebTestClientContextCustomizerFactory
org.springframework.boot.test.web.reactive.server.WebTestClientContextCustomizerFactory
# Test Execution Listeners
org.springframework.test.context.TestExecutionListener=\