Fix WebGraphQlTester auto-registration for SpringBootTest

Prior to this commit, the `GraphQlTesterContextCustomizer` would
register a `WebGraphQlTester` instance as a `GraphQlTester` bean., only
exposing the `GraphQlTester` type. This is not in line with the
documentation and also does not register the bean definition with the
most specific type.
With this issue, a `@SpringBootTest` integration test will not be
injected with a `WebGraphQlTester` if it asks one.

This commit ensures that the `WebGraphQlTester` is registered as such
and that all related classes are renamed as a result.

Fixes gh-29250
This commit is contained in:
Brian Clozel 2022-01-03 16:00:04 +01:00
parent c3abf96d1f
commit 0d616b8924
6 changed files with 33 additions and 34 deletions

View File

@ -35,7 +35,6 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
@ -46,32 +45,32 @@ import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link ContextCustomizer} for {@link GraphQlTester}.
* {@link ContextCustomizer} for {@link WebGraphQlTester}.
*
* @author Brian Clozel
*/
class GraphQlTesterContextCustomizer implements ContextCustomizer {
class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(mergedConfig.getTestClass(),
SpringBootTest.class);
if (springBootTest.webEnvironment().isEmbedded()) {
registerGraphQlTester(context);
registerWebGraphQlTester(context);
}
}
private void registerGraphQlTester(ConfigurableApplicationContext context) {
private void registerWebGraphQlTester(ConfigurableApplicationContext context) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
if (beanFactory instanceof BeanDefinitionRegistry) {
registerGraphQlTester((BeanDefinitionRegistry) beanFactory);
registerWebGraphQlTester((BeanDefinitionRegistry) beanFactory);
}
}
private void registerGraphQlTester(BeanDefinitionRegistry registry) {
RootBeanDefinition definition = new RootBeanDefinition(GraphQlTesterRegistrar.class);
private void registerWebGraphQlTester(BeanDefinitionRegistry registry) {
RootBeanDefinition definition = new RootBeanDefinition(WebGraphQlTesterRegistrar.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(GraphQlTesterRegistrar.class.getName(), definition);
registry.registerBeanDefinition(WebGraphQlTesterRegistrar.class.getName(), definition);
}
@Override
@ -84,7 +83,7 @@ class GraphQlTesterContextCustomizer implements ContextCustomizer {
return getClass().hashCode();
}
private static class GraphQlTesterRegistrar
private static class WebGraphQlTesterRegistrar
implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware {
private BeanFactory beanFactory;
@ -97,9 +96,9 @@ class GraphQlTesterContextCustomizer implements ContextCustomizer {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory,
GraphQlTester.class, false, false).length == 0) {
WebGraphQlTester.class, false, false).length == 0) {
registry.registerBeanDefinition(WebGraphQlTester.class.getName(),
new RootBeanDefinition(GraphQlTesterFactory.class));
new RootBeanDefinition(WebGraphQlTesterFactory.class));
}
}
@ -115,7 +114,7 @@ class GraphQlTesterContextCustomizer implements ContextCustomizer {
}
public static class GraphQlTesterFactory implements FactoryBean<GraphQlTester>, ApplicationContextAware {
public static class WebGraphQlTesterFactory implements FactoryBean<WebGraphQlTester>, ApplicationContextAware {
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
@ -123,7 +122,7 @@ class GraphQlTesterContextCustomizer implements ContextCustomizer {
private ApplicationContext applicationContext;
private GraphQlTester object;
private WebGraphQlTester object;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
@ -137,11 +136,11 @@ class GraphQlTesterContextCustomizer implements ContextCustomizer {
@Override
public Class<?> getObjectType() {
return GraphQlTester.class;
return WebGraphQlTester.class;
}
@Override
public GraphQlTester getObject() throws Exception {
public WebGraphQlTester getObject() throws Exception {
if (this.object == null) {
this.object = createGraphQlTester();
}

View File

@ -30,11 +30,11 @@ import org.springframework.util.ClassUtils;
* {@link ContextCustomizerFactory} for {@link GraphQlTester}.
*
* @author Brian Clozel
* @see GraphQlTesterContextCustomizer
* @see WebGraphQlTesterContextCustomizer
*/
class GraphQlTesterContextCustomizerFactory implements ContextCustomizerFactory {
class WebGraphQlTesterContextCustomizerFactory implements ContextCustomizerFactory {
private static final String GRAPHQLTESTER_CLASS = "org.springframework.graphql.test.tester.GraphQlTester";
private static final String WEBGRAPHQLTESTER_CLASS = "org.springframework.graphql.test.tester.WebGraphQlTester";
private static final String WEBTESTCLIENT_CLASS = "org.springframework.test.web.reactive.server.WebTestClient";
@ -43,12 +43,12 @@ class GraphQlTesterContextCustomizerFactory implements ContextCustomizerFactory
List<ContextConfigurationAttributes> configAttributes) {
SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
SpringBootTest.class);
return (springBootTest != null && isGraphQlTesterPresent()) ? new GraphQlTesterContextCustomizer() : null;
return (springBootTest != null && isGraphQlTesterPresent()) ? new WebGraphQlTesterContextCustomizer() : null;
}
private boolean isGraphQlTesterPresent() {
return ClassUtils.isPresent(WEBTESTCLIENT_CLASS, getClass().getClassLoader())
&& ClassUtils.isPresent(GRAPHQLTESTER_CLASS, getClass().getClassLoader());
&& ClassUtils.isPresent(WEBGRAPHQLTESTER_CLASS, getClass().getClassLoader());
}
}

View File

@ -2,7 +2,7 @@
org.springframework.test.context.ContextCustomizerFactory=\
org.springframework.boot.test.context.ImportsContextCustomizerFactory,\
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\
org.springframework.boot.test.graphql.tester.GraphQlTesterContextCustomizerFactory,\
org.springframework.boot.test.graphql.tester.WebGraphQlTesterContextCustomizerFactory,\
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory,\
org.springframework.boot.test.web.client.TestRestTemplateContextCustomizerFactory,\

View File

@ -28,7 +28,7 @@ import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFacto
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ContextPathCompositeHandler;
@ -38,17 +38,17 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.test.annotation.DirtiesContext;
/**
* Integration test for {@link GraphQlTesterContextCustomizer}.
* Integration test for {@link WebGraphQlTesterContextCustomizer}.
*
* @author Brian Clozel
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.main.web-application-type=reactive")
@DirtiesContext
class GraphQlTesterContextCustomizerIntegrationTests {
class WebGraphQlTesterContextCustomizerIntegrationTests {
@Autowired
GraphQlTester graphQlTester;
WebGraphQlTester graphQlTester;
@Test
void shouldHandleGraphQlRequests() {

View File

@ -28,7 +28,7 @@ import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFacto
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ContextPathCompositeHandler;
@ -38,17 +38,17 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.test.context.TestPropertySource;
/**
* Tests for {@link GraphQlTesterContextCustomizer} with a custom context path for a
* Tests for {@link WebGraphQlTesterContextCustomizer} with a custom context path for a
* Reactive web application.
*
* @author Brian Clozel
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = { "spring.main.web-application-type=reactive", "spring.webflux.base-path=/test" })
class GraphQlTesterContextCustomizerWithCustomBasePathTests {
class WebGraphQlTesterContextCustomizerWithCustomBasePathTests {
@Autowired
GraphQlTester graphQlTester;
WebGraphQlTester graphQlTester;
@Test
void shouldHandleGraphQlRequests() {

View File

@ -24,7 +24,7 @@ import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactor
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.web.bind.annotation.PostMapping;
@ -32,17 +32,17 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Tests for {@link GraphQlTesterContextCustomizer} with a custom context path for a
* Tests for {@link WebGraphQlTesterContextCustomizer} with a custom context path for a
* Servlet web application.
*
* @author Brian Clozel
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = "server.servlet.context-path=/test")
class GraphQlTesterContextCustomizerWithCustomContextPathTests {
class WebGraphQlTesterContextCustomizerWithCustomContextPathTests {
@Autowired
GraphQlTester graphQlTester;
WebGraphQlTester graphQlTester;
@Test
void shouldHandleGraphQlRequests() {