Upgrade to Spring GraphQL 1.0.0-SNAPSHOT

This commit switches to 1.0.0-SNAPSHOT for Spring GraphQL, before its
upcoming 1.0.0-M6 version.

This commit adapts to the changes introduced in
spring-projects/spring-graphql#317 : now that `GraphQlClient` has been
introduced, `GraphQlTester` has been aligned with the new
infrastructure. The `@GraphQlTest` and `@SpringBootTest` testing support
is now using different variants for each.

All samples have been updated to use the proper GraphQL terminology, see
and spring-projects/spring-graphql#310 .

See gh-29637
pull/30406/head
Brian Clozel 3 years ago
parent dfd4097436
commit 81754c8bc4

@ -26,7 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.graphql.security.ReactiveSecurityDataFetcherExceptionResolver;
import org.springframework.graphql.execution.ReactiveSecurityDataFetcherExceptionResolver;
import org.springframework.graphql.web.webflux.GraphQlHttpHandler;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;

@ -26,8 +26,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.graphql.security.SecurityContextThreadLocalAccessor;
import org.springframework.graphql.security.SecurityDataFetcherExceptionResolver;
import org.springframework.graphql.execution.SecurityContextThreadLocalAccessor;
import org.springframework.graphql.execution.SecurityDataFetcherExceptionResolver;
import org.springframework.graphql.web.webmvc.GraphQlHttpHandler;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -30,7 +30,7 @@ import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.data.GraphQlRepository;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.graphql.test.tester.GraphQlServiceTester;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
@ -55,8 +55,8 @@ class GraphQlQueryByExampleAutoConfigurationTests {
void shouldRegisterDataFetcherForQueryByExampleRepositories() {
this.contextRunner.run((context) -> {
GraphQlService graphQlService = context.getBean(GraphQlService.class);
GraphQlTester graphQlTester = GraphQlTester.create(graphQlService);
graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
GraphQlServiceTester graphQlTester = GraphQlServiceTester.create(graphQlService);
graphQlTester.document("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
.isEqualTo("Test title");
});
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -30,6 +30,7 @@ import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.data.GraphQlRepository;
import org.springframework.graphql.test.tester.GraphQlServiceTester;
import org.springframework.graphql.test.tester.GraphQlTester;
import static org.mockito.ArgumentMatchers.any;
@ -55,8 +56,8 @@ class GraphQlQuerydslAutoConfigurationTests {
void shouldRegisterDataFetcherForQueryDslRepositories() {
this.contextRunner.run((context) -> {
GraphQlService graphQlService = context.getBean(GraphQlService.class);
GraphQlTester graphQlTester = GraphQlTester.create(graphQlService);
graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
GraphQlTester graphQlTester = GraphQlServiceTester.create(graphQlService);
graphQlTester.document("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
.isEqualTo("Test title");
});
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -29,6 +29,7 @@ import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.data.GraphQlRepository;
import org.springframework.graphql.test.tester.GraphQlServiceTester;
import org.springframework.graphql.test.tester.GraphQlTester;
import static org.mockito.ArgumentMatchers.any;
@ -54,8 +55,8 @@ class GraphQlReactiveQueryByExampleAutoConfigurationTests {
void shouldRegisterDataFetcherForQueryByExampleRepositories() {
this.contextRunner.run((context) -> {
GraphQlService graphQlService = context.getBean(GraphQlService.class);
GraphQlTester graphQlTester = GraphQlTester.create(graphQlService);
graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
GraphQlTester graphQlTester = GraphQlServiceTester.create(graphQlService);
graphQlTester.document("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
.isEqualTo("Test title");
});
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -29,6 +29,7 @@ import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.data.GraphQlRepository;
import org.springframework.graphql.test.tester.GraphQlServiceTester;
import org.springframework.graphql.test.tester.GraphQlTester;
import static org.mockito.ArgumentMatchers.any;
@ -54,8 +55,8 @@ class GraphQlReactiveQuerydslAutoConfigurationTests {
void shouldRegisterDataFetcherForQueryDslRepositories() {
this.contextRunner.run((context) -> {
GraphQlService graphQlService = context.getBean(GraphQlService.class);
GraphQlTester graphQlTester = GraphQlTester.create(graphQlService);
graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
GraphQlTester graphQlTester = GraphQlServiceTester.create(graphQlService);
graphQlTester.document("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class)
.isEqualTo("Test title");
});
}

@ -37,8 +37,8 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.ErrorType;
import org.springframework.graphql.execution.ReactiveSecurityDataFetcherExceptionResolver;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
import org.springframework.graphql.security.ReactiveSecurityDataFetcherExceptionResolver;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.security.access.prepost.PreAuthorize;

@ -34,8 +34,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.ErrorType;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
import org.springframework.graphql.security.SecurityContextThreadLocalAccessor;
import org.springframework.graphql.security.SecurityDataFetcherExceptionResolver;
import org.springframework.graphql.execution.SecurityContextThreadLocalAccessor;
import org.springframework.graphql.execution.SecurityDataFetcherExceptionResolver;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.security.access.prepost.PreAuthorize;

@ -1682,7 +1682,7 @@ bom {
]
}
}
library("Spring GraphQL", "1.0.0-M5") {
library("Spring GraphQL", "1.0.0-SNAPSHOT") {
group("org.springframework.graphql") {
modules = [
"spring-graphql",

@ -435,8 +435,12 @@ Spring GraphQL offers a dedicated testing support module; you'll need to add it
}
----
This testing module ships the {spring-graphql-docs}/testing.html#testing-webgraphqltester[WebGraphQlTester].
This testing module ships the {spring-graphql-docs}/#testing-graphqltester[GraphQlTester].
The tester is heavily used in test, so be sure to become familiar with using it.
There are `GraphQlTester` variants and Spring Boot will auto-configure them depending on the type of tests:
* the `GraphQlServiceTester` performs tests on the server side, without a client nor a transport
* the `HttpGraphQlTester` performs tests with a client that connects to a server, with or without a live server
Spring Boot helps you to test your {spring-graphql-docs}#controllers[Spring GraphQL Controllers] with the `@GraphQlTest` annotation.
`@GraphQlTest` auto-configures the Spring GraphQL infrastructure, without any transport nor server being involved.
@ -452,8 +456,11 @@ Often, `@GraphQlTest` is limited to a set of controllers and used in combination
include::code:GreetingControllerTests[]
TIP: You can also auto-configure `WebGraphQlTester` in a non-`@GraphQlTest` (such as `@SpringBootTest`) by annotating it with `@AutoConfigureWebGraphQlTester`.
`@SpringBootTest` tests are full integration tests and involve the entire application.
When using a random or defined port, a live server is configured and an `HttpGraphQlTester` bean is contributed automatically so you can use it to test your server.
When a MOCK environment is configured, you can also request an `HttpGraphQlTester` bean by annotating your test class with `@AutoConfigureHttpGraphQlTester`:
include::code:GraphQlIntegrationTests[]
[[features.testing.spring-boot-applications.autoconfigured-spring-data-cassandra]]

@ -0,0 +1,40 @@
/*
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.springgraphqltests;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
@AutoConfigureHttpGraphQlTester
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class GraphQlIntegrationTests {
@Test
void shouldGreetWithSpecificName(@Autowired HttpGraphQlTester graphQlTester) {
HttpGraphQlTester authenticatedTester = graphQlTester.mutate()
.webTestClient(
(client) -> client.defaultHeaders((headers) -> headers.setBasicAuth("admin", "ilovespring")))
.build();
authenticatedTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Alice!");
}
}

@ -31,13 +31,13 @@ class GreetingControllerTests {
@Test
void shouldGreetWithSpecificName() {
this.graphQlTester.query("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
this.graphQlTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Alice!");
}
@Test
void shouldGreetWithDefaultName() {
this.graphQlTester.query("{ greeting } ").execute().path("greeting").entity(String.class)
this.graphQlTester.document("{ greeting } ").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Spring!");
}

@ -0,0 +1,42 @@
/*
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.springgraphqltests
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.graphql.test.tester.HttpGraphQlTester
import org.springframework.http.HttpHeaders
import org.springframework.test.web.reactive.server.WebTestClient
@AutoConfigureHttpGraphQlTester
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class GraphQlIntegrationTests {
@Test
fun shouldGreetWithSpecificName(@Autowired graphQlTester: HttpGraphQlTester) {
val authenticatedTester = graphQlTester.mutate()
.webTestClient { client: WebTestClient.Builder ->
client.defaultHeaders { headers: HttpHeaders ->
headers.setBasicAuth("admin", "ilovespring")
}
}.build()
authenticatedTester.document("{ greeting(name: \"Alice\") } ").execute()
.path("greeting").entity(String::class.java).isEqualTo("Hello, Alice!")
}
}

@ -30,13 +30,13 @@ internal class GreetingControllerTests {
@Test
fun shouldGreetWithSpecificName() {
graphQlTester.query("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String::class.java)
graphQlTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String::class.java)
.isEqualTo("Hello, Alice!")
}
@Test
fun shouldGreetWithDefaultName() {
graphQlTester.query("{ greeting } ").execute().path("greeting").entity(String::class.java)
graphQlTester.document("{ greeting } ").execute().path("greeting").entity(String::class.java)
.isEqualTo("Hello, Spring!")
}

@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 the original author or authors.
* Copyright 2020-2022 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.
@ -31,7 +31,7 @@ import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AliasFor;
@ -67,9 +67,9 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
* and other components required for the tests.
* <p>
* To load your full application configuration instead and test via
* {@code WebGraphQlTester}, consider using
* {@code HttpGraphQlTester}, consider using
* {@link org.springframework.boot.test.context.SpringBootTest @SpringBootTest} combined
* with {@link AutoConfigureWebGraphQlTester @AutoConfigureWebGraphQlTester}.
* with {@link AutoConfigureHttpGraphQlTester @AutoConfigureHttpGraphQlTester}.
*
* @author Brian Clozel
* @since 2.7.0

@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 the original author or authors.
* Copyright 2020-2022 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.
@ -26,10 +26,10 @@ import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
/**
* Annotation that can be applied to a test class to enable a {@link WebGraphQlTester}.
* Annotation that can be applied to a test class to enable a {@link HttpGraphQlTester}.
*
* <p>
* This annotation should be used with
@ -38,7 +38,7 @@ import org.springframework.graphql.test.tester.WebGraphQlTester;
*
* @author Brian Clozel
* @since 2.7.0
* @see WebGraphQlTesterAutoConfiguration
* @see HttpGraphQlTesterAutoConfiguration
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ -47,6 +47,6 @@ import org.springframework.graphql.test.tester.WebGraphQlTester;
@AutoConfigureMockMvc
@AutoConfigureWebTestClient
@ImportAutoConfiguration
public @interface AutoConfigureWebGraphQlTester {
public @interface AutoConfigureHttpGraphQlTester {
}

@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.test.tester.GraphQlServiceTester;
import org.springframework.graphql.test.tester.GraphQlTester;
/**
@ -40,8 +41,8 @@ public class GraphQlTesterAutoConfiguration {
@Bean
@ConditionalOnBean(GraphQlService.class)
@ConditionalOnMissingBean
public GraphQlTester graphQlTester(GraphQlService graphQlService) {
return GraphQlTester.create(graphQlService);
public GraphQlServiceTester graphQlTester(GraphQlService graphQlService) {
return GraphQlServiceTester.create(graphQlService);
}
}

@ -24,26 +24,27 @@ import org.springframework.boot.autoconfigure.graphql.GraphQlProperties;
import org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.client.WebClient;
/**
* Auto-configuration for {@link WebGraphQlTester}.
* Auto-configuration for {@link HttpGraphQlTester}.
*
* @author Brian Clozel
* @since 2.7.0
*/
@AutoConfiguration(after = { WebTestClientAutoConfiguration.class, MockMvcAutoConfiguration.class })
@ConditionalOnClass({ WebClient.class, WebTestClient.class, WebGraphQlTester.class })
public class WebGraphQlTesterAutoConfiguration {
public class HttpGraphQlTesterAutoConfiguration {
@Bean
@ConditionalOnBean(WebTestClient.class)
@ConditionalOnMissingBean
public WebGraphQlTester webTestClientGraphQlTester(WebTestClient webTestClient, GraphQlProperties properties) {
public HttpGraphQlTester webTestClientGraphQlTester(WebTestClient webTestClient, GraphQlProperties properties) {
WebTestClient mutatedWebTestClient = webTestClient.mutate().baseUrl(properties.getPath()).build();
return WebGraphQlTester.create(mutatedWebTestClient);
return HttpGraphQlTester.create(mutatedWebTestClient);
}
}

@ -0,0 +1,2 @@
# AutoConfigureHttpGraphQlTester auto-configuration imports
org.springframework.boot.test.autoconfigure.graphql.tester.HttpGraphQlTesterAutoConfiguration

@ -1,2 +0,0 @@
# AutoConfigureWebGraphQlTester auto-configuration imports
org.springframework.boot.test.autoconfigure.graphql.tester.WebGraphQlTesterAutoConfiguration

@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 the original author or authors.
* Copyright 2020-2022 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.
@ -35,7 +35,7 @@ public class GraphQlTestIntegrationTest {
@Test
void getBookdByIdShouldReturnTestBook() {
String query = "{ bookById(id: \"book-1\"){ id name pageCount author } }";
this.graphQlTester.query(query).execute().path("data.bookById.id").entity(String.class).isEqualTo("42");
this.graphQlTester.document(query).execute().path("data.bookById.id").entity(String.class).isEqualTo("42");
}
}

@ -62,10 +62,17 @@ import org.springframework.web.context.WebApplicationContext;
* including the ability to start a fully running web server listening on a
* {@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} 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>
* <p>
* Can register the following beans for web tests that are using a fully running web
* server:
* <ul>
* <li>{@link org.springframework.boot.test.web.client.TestRestTemplate
* TestRestTemplate}</li>
* <li>{@link org.springframework.test.web.reactive.server.WebTestClient
* WebTestClient}</li>
* <li>{@link org.springframework.graphql.test.tester.HttpGraphQlTester
* HttpGraphQlTester}</li>
* </ul>
*
* @author Phillip Webb

@ -35,7 +35,7 @@ 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.WebGraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextAnnotationUtils;
@ -45,32 +45,32 @@ import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link ContextCustomizer} for {@link WebGraphQlTester}.
* {@link ContextCustomizer} for {@link HttpGraphQlTester}.
*
* @author Brian Clozel
*/
class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
class HttpGraphQlTesterContextCustomizer implements ContextCustomizer {
@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(mergedConfig.getTestClass(),
SpringBootTest.class);
if (springBootTest.webEnvironment().isEmbedded()) {
registerWebGraphQlTester(context);
registerHttpGraphQlTester(context);
}
}
private void registerWebGraphQlTester(ConfigurableApplicationContext context) {
private void registerHttpGraphQlTester(ConfigurableApplicationContext context) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
if (beanFactory instanceof BeanDefinitionRegistry) {
registerWebGraphQlTester((BeanDefinitionRegistry) beanFactory);
registerHttpGraphQlTester((BeanDefinitionRegistry) beanFactory);
}
}
private void registerWebGraphQlTester(BeanDefinitionRegistry registry) {
RootBeanDefinition definition = new RootBeanDefinition(WebGraphQlTesterRegistrar.class);
private void registerHttpGraphQlTester(BeanDefinitionRegistry registry) {
RootBeanDefinition definition = new RootBeanDefinition(HttpGraphQlTesterRegistrar.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(WebGraphQlTesterRegistrar.class.getName(), definition);
registry.registerBeanDefinition(HttpGraphQlTesterRegistrar.class.getName(), definition);
}
@Override
@ -83,7 +83,7 @@ class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
return getClass().hashCode();
}
private static class WebGraphQlTesterRegistrar
private static class HttpGraphQlTesterRegistrar
implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware {
private BeanFactory beanFactory;
@ -96,9 +96,9 @@ class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory,
WebGraphQlTester.class, false, false).length == 0) {
registry.registerBeanDefinition(WebGraphQlTester.class.getName(),
new RootBeanDefinition(WebGraphQlTesterFactory.class));
HttpGraphQlTester.class, false, false).length == 0) {
registry.registerBeanDefinition(HttpGraphQlTester.class.getName(),
new RootBeanDefinition(HttpGraphQlTesterFactory.class));
}
}
@ -114,7 +114,7 @@ class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
}
public static class WebGraphQlTesterFactory implements FactoryBean<WebGraphQlTester>, ApplicationContextAware {
public static class HttpGraphQlTesterFactory implements FactoryBean<HttpGraphQlTester>, ApplicationContextAware {
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
@ -122,7 +122,7 @@ class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
private ApplicationContext applicationContext;
private WebGraphQlTester object;
private HttpGraphQlTester object;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
@ -136,23 +136,23 @@ class WebGraphQlTesterContextCustomizer implements ContextCustomizer {
@Override
public Class<?> getObjectType() {
return WebGraphQlTester.class;
return HttpGraphQlTester.class;
}
@Override
public WebGraphQlTester getObject() throws Exception {
public HttpGraphQlTester getObject() throws Exception {
if (this.object == null) {
this.object = createGraphQlTester();
}
return this.object;
}
private WebGraphQlTester createGraphQlTester() {
private HttpGraphQlTester createGraphQlTester() {
WebTestClient webTestClient = this.applicationContext.getBean(WebTestClient.class);
boolean sslEnabled = isSslEnabled(this.applicationContext);
String port = this.applicationContext.getEnvironment().getProperty("local.server.port", "8080");
WebTestClient mutatedWebClient = webTestClient.mutate().baseUrl(getBaseUrl(sslEnabled, port)).build();
return WebGraphQlTester.create(mutatedWebClient);
return HttpGraphQlTester.create(mutatedWebClient);
}
private String getBaseUrl(boolean sslEnabled, String port) {

@ -19,7 +19,7 @@ package org.springframework.boot.test.graphql.tester;
import java.util.List;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.GraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
@ -27,14 +27,14 @@ import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.util.ClassUtils;
/**
* {@link ContextCustomizerFactory} for {@link GraphQlTester}.
* {@link ContextCustomizerFactory} for {@link HttpGraphQlTester}.
*
* @author Brian Clozel
* @see WebGraphQlTesterContextCustomizer
* @see HttpGraphQlTesterContextCustomizer
*/
class WebGraphQlTesterContextCustomizerFactory implements ContextCustomizerFactory {
class HttpGraphQlTesterContextCustomizerFactory implements ContextCustomizerFactory {
private static final String WEBGRAPHQLTESTER_CLASS = "org.springframework.graphql.test.tester.WebGraphQlTester";
private static final String HTTPGRAPHQLTESTER_CLASS = "org.springframework.graphql.test.tester.HttpGraphQlTester";
private static final String WEBTESTCLIENT_CLASS = "org.springframework.test.web.reactive.server.WebTestClient";
@ -43,12 +43,12 @@ class WebGraphQlTesterContextCustomizerFactory implements ContextCustomizerFacto
List<ContextConfigurationAttributes> configAttributes) {
SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(testClass,
SpringBootTest.class);
return (springBootTest != null && isGraphQlTesterPresent()) ? new WebGraphQlTesterContextCustomizer() : null;
return (springBootTest != null && isGraphQlTesterPresent()) ? new HttpGraphQlTesterContextCustomizer() : null;
}
private boolean isGraphQlTesterPresent() {
return ClassUtils.isPresent(WEBTESTCLIENT_CLASS, getClass().getClassLoader())
&& ClassUtils.isPresent(WEBGRAPHQLTESTER_CLASS, getClass().getClassLoader());
&& ClassUtils.isPresent(HTTPGRAPHQLTESTER_CLASS, getClass().getClassLoader());
}
}

@ -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.WebGraphQlTesterContextCustomizerFactory,\
org.springframework.boot.test.graphql.tester.HttpGraphQlTesterContextCustomizerFactory,\
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory,\
org.springframework.boot.test.web.client.TestRestTemplateContextCustomizerFactory,\

@ -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.WebGraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ContextPathCompositeHandler;
@ -38,21 +38,21 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.test.annotation.DirtiesContext;
/**
* Integration test for {@link WebGraphQlTesterContextCustomizer}.
* Integration test for {@link HttpGraphQlTesterContextCustomizer}.
*
* @author Brian Clozel
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.main.web-application-type=reactive")
@DirtiesContext
class WebGraphQlTesterContextCustomizerIntegrationTests {
class HttpGraphQlTesterContextCustomizerIntegrationTests {
@Autowired
WebGraphQlTester graphQlTester;
HttpGraphQlTester graphQlTester;
@Test
void shouldHandleGraphQlRequests() {
this.graphQlTester.query("{}").executeAndVerify();
this.graphQlTester.document("{}").executeAndVerify();
}
@Configuration(proxyBeanMethods = false)

@ -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.WebGraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ContextPathCompositeHandler;
@ -38,21 +38,21 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.test.context.TestPropertySource;
/**
* Tests for {@link WebGraphQlTesterContextCustomizer} with a custom context path for a
* Tests for {@link HttpGraphQlTesterContextCustomizer} 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 WebGraphQlTesterContextCustomizerWithCustomBasePathTests {
class HttpGraphQlTesterContextCustomizerWithCustomBasePathTests {
@Autowired
WebGraphQlTester graphQlTester;
HttpGraphQlTester graphQlTester;
@Test
void shouldHandleGraphQlRequests() {
this.graphQlTester.query("{}").executeAndVerify();
this.graphQlTester.document("{}").executeAndVerify();
}
@Configuration(proxyBeanMethods = false)

@ -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.WebGraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.web.bind.annotation.PostMapping;
@ -32,21 +32,21 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Tests for {@link WebGraphQlTesterContextCustomizer} with a custom context path for a
* Tests for {@link HttpGraphQlTesterContextCustomizer} 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 WebGraphQlTesterContextCustomizerWithCustomContextPathTests {
class HttpGraphQlTesterContextCustomizerWithCustomContextPathTests {
@Autowired
WebGraphQlTester graphQlTester;
HttpGraphQlTester graphQlTester;
@Test
void shouldHandleGraphQlRequests() {
this.graphQlTester.query("{}").executeAndVerify();
this.graphQlTester.document("{}").executeAndVerify();
}
@Configuration(proxyBeanMethods = false)

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 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.
@ -19,23 +19,23 @@ package smoketest.graphql;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.execution.ErrorType;
import org.springframework.graphql.test.tester.WebGraphQlTester;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
@AutoConfigureWebGraphQlTester
@AutoConfigureHttpGraphQlTester
class GreetingControllerTests {
@Autowired
private WebGraphQlTester graphQlTester;
private HttpGraphQlTester graphQlTester;
@Test
void shouldUnauthorizeAnonymousUsers() {
this.graphQlTester.queryName("greeting").variable("name", "Brian").execute().errors().satisfy((errors) -> {
this.graphQlTester.documentName("greeting").variable("name", "Brian").execute().errors().satisfy((errors) -> {
assertThat(errors).hasSize(1);
assertThat(errors.get(0).getErrorType()).isEqualTo(ErrorType.UNAUTHORIZED);
});
@ -43,15 +43,23 @@ class GreetingControllerTests {
@Test
void shouldGreetWithSpecificName() {
this.graphQlTester.queryName("greeting").variable("name", "Brian")
.httpHeaders((headers) -> headers.setBasicAuth("admin", "admin")).execute().path("greeting")
.entity(String.class).isEqualTo("Hello, Brian!");
HttpGraphQlTester authenticated = withAdminCredentials(this.graphQlTester);
authenticated.documentName("greeting").variable("name", "Brian").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Brian!");
}
@Test
void shouldGreetWithDefaultName() {
this.graphQlTester.query("{ greeting }").httpHeaders((headers) -> headers.setBasicAuth("admin", "admin"))
.execute().path("greeting").entity(String.class).isEqualTo("Hello, Spring!");
HttpGraphQlTester authenticated = withAdminCredentials(this.graphQlTester);
authenticated.document("{ greeting }").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Spring!");
}
private HttpGraphQlTester withAdminCredentials(HttpGraphQlTester graphQlTester) {
return graphQlTester.mutate()
.webTestClient(
(httpClient) -> httpClient.defaultHeaders((headers) -> headers.setBasicAuth("admin", "admin")))
.build();
}
}

@ -30,13 +30,13 @@ class ProjectControllerTests {
@Test
void shouldFindSpringGraphQl() {
this.graphQlTester.query("{ project(slug: \"spring-graphql\") { name } }").execute().path("project.name")
this.graphQlTester.document("{ project(slug: \"spring-graphql\") { name } }").execute().path("project.name")
.entity(String.class).isEqualTo("Spring GraphQL");
}
@Test
void shouldNotFindUnknownProject() {
this.graphQlTester.query("{ project(slug: \"spring-unknown\") { name } }").execute().path("project.name")
this.graphQlTester.document("{ project(slug: \"spring-unknown\") { name } }").execute().path("project.name")
.valueDoesNotExist();
}

Loading…
Cancel
Save