Update docs and samples on "slice" tests

See gh-75
This commit is contained in:
Rossen Stoyanchev
2021-10-28 12:29:16 +01:00
parent 59d5458333
commit 6dabd7c212
5 changed files with 86 additions and 45 deletions

View File

@@ -20,8 +20,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.boot.test.GraphQlTest;
import org.springframework.graphql.test.tester.GraphQlTester;
@@ -29,10 +28,8 @@ import org.springframework.graphql.test.tester.GraphQlTester;
/**
* GraphQL query tests directly via {@link GraphQL}.
*/
@GraphQlTest(controllers = SampleController.class,
includeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = {ContextWebFilter.class, DataRepository.class}))
@GraphQlTest(SampleController.class)
@Import(TestConfig.class)
public class QueryTests {
private GraphQlTester graphQlTester;

View File

@@ -22,8 +22,7 @@ import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.graphql.GraphQlService;
import org.springframework.graphql.boot.test.GraphQlTest;
import org.springframework.graphql.test.tester.GraphQlTester;
@@ -31,10 +30,8 @@ import org.springframework.graphql.test.tester.GraphQlTester;
/**
* GraphQL subscription tests directly via {@link GraphQL}.
*/
@GraphQlTest(controllers = SampleController.class,
includeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = {ContextWebFilter.class, DataRepository.class}))
@GraphQlTest(SampleController.class)
@Import(TestConfig.class)
public class SubscriptionTests {
private GraphQlTester graphQlTester;

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2002-2021 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 io.spring.sample.graphql;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Collaborator and additional components for {@link SampleController} slice tests.
*/
@Configuration
class TestConfig {
@Bean
public ContextWebFilter contextWebFilter() {
return new ContextWebFilter();
}
@Bean
public DataRepository dataRepository() {
return new DataRepository();
}
}

View File

@@ -440,25 +440,44 @@ repositories {
The following sections cover a range of options for testing a Spring GraphQL application.
[[boot-graphql-testing-graphqltest]]
=== Standalone GraphQL Server Tests
=== GraphQL Slice Tests
Use `@GraphQlTest` to test Spring GraphQL data `@Controller` and related GraphQL components
without involving a Web transport or a Web framework (Spring MVC or WebFlux).
`@GraphQlTest` auto-configures Spring GraphQL infrastructure and limits scanned beans to
`@Controller`, `RuntimeWiringConfigurer`, `JsonComponent`, `WebInterceptor`, `Converter`,
and `GenericConverter`, but excludes regular `@Component` and `@ConfigurationProperties`
beans. To include `@ConfigurationProperties` beans, use `@EnableConfigurationProperties`.
Use `@GraphQlTest` on a test class to create GraphQL tests focused on GraphQL request
execution, without involving a Web layer, and loading only a subset of the application
configuration.
By default, `@GraphQlTest` limits scanning to the following beans:
- `@Controller`
- `RuntimeWiringConfigurer`
- `JsonComponent`
- `Converter`
- `GenericConverter`
Use the `controllers` attribute of `@GraphQlTest` to specify a controller class, or to
list all data controllers required to perform requests in a test class. Leaving it empty,
includes all controllers.
To add collaborator and/or other components to a test class, use one of the following:
- `@MockBean` fields in the test class.
- `@Import` an `@Configuration` class into the test class.
- Create a `@TestConfiguration` nested class.
- Broaden the component scan via `includeFilters` on `@GraphQlTest`.
To add properties, use the `properties` attribute of `@GraphQlTest`, or add
`@EnableConfigurationProperties` on the test class.
[NOTE]
====
The arrangement is similar to the
{spring-boot-ref-docs}/features.html#features.testing.spring-boot-applications.spring-mvc-tests[@WevMvcTest support],
except there is no web framework in use, and `GraphQlService` is used to perform requests.
`@GraphQlTest` is comparable to
{spring-boot-ref-docs}/features.html#features.testing.spring-boot-applications.spring-mvc-tests[@WevMvcTest],
which also uses test "slices" to create focused Web controller tests.
====
[source,java,indent=0,subs="verbatim,quotes"]
----
@GraphQlTest(controllers = BookController.class)
@GraphQlTest(BookController.class)
public class BookControllerTests {
@Autowired
@@ -478,11 +497,11 @@ public class BookControllerTests {
}
----
This mode is useful to test subscriptions without a WebSocket transport.
This mode is useful to test subscriptions without WebSocket.
[source,java,indent=0,subs="verbatim,quotes"]
----
@GraphQlTest(controllers = GreetingController.class)
@GraphQlTest(GreetingController.class)
public class GreetingControllerTests {
@Autowired
@@ -505,20 +524,9 @@ public class GreetingControllerTests {
}
----
`GraphQlService` is used to perform the above test. It represents common infrastructure
for HTTP and WebSocket transports that both Spring WebMvc and WebFlux handlers delegate to.
Therefore, it does not involve a web framework and does not apply the `WebInterceptor`
chain before and after the call to the GraphQL Java engine, which returns a Reactive
Streams `Publisher`.
`GraphQlService` performS the above request by calling directly the GraphQL Java engine,
which returns a Reactive Streams `Publisher`.
[NOTE]
.Testing multiple controllers with `@GraphQlTest`
====
Because GraphQL is not about REST endpoints but navigating relations in an object graph,
multiple `@Controller` components can be involved in a single query.
For this case, the `@GraphQlTest` annotation supports testing multiple controllers through
its `controllers` attribute.
====
[[boot-graphql-testing-mock]]
=== Client and Mock Server Tests

View File

@@ -1,9 +1,9 @@
[[testing]]
= Testing
You can test GraphQL requests using Spring's `WebTestClient`, just send and receive
JSON, but a number of GraphQL specific details make this approach more cumbersome than it
should be.
It's possible to test GraphQL requests with Spring's `WebTestClient`, just sending and
receiving JSON, but a number of GraphQL specific details make this approach more
cumbersome than is necessary.
@@ -12,7 +12,6 @@ should be.
`GraphQlTester` defines a workflow to test GraphQL requests with the following benefits:
- Verify GraphQL responses are 200 (OK).
- Verify no unexpected errors under the "errors" key in the response.
- Decode under the "data" key in the response.
- Use JsonPath to decode different parts of the response.
@@ -38,7 +37,10 @@ To create `GraphQlTester`, you only need a `GraphQlService`, and no transport:
== `WebGraphQlTester`
`WebGraphQlTester` extends `GraphQlTester` to add a workflow and configuration specific
to <<index#web-transports>>. You need one of the following inputs to create it:
to <<index#web-transports>>, and it always verifies GraphQL HTTP responses are 200 (OK).
To create `WebGraphQlTester`, you need one of the following inputs:
- `WebTestClient` -- perform requests as an HTTP client, either against <<index#web-http>>
handlers without a server, or against a live server.
@@ -61,7 +63,7 @@ For Spring WebFlux without a server, you can point to your Spring configuration:
WebGraphQlTester tester = WebGraphQlTester.builder(client).build();
----
For Spring MVC without a server, use the `MockMvcWebTestClient` builder:
For Spring MVC without a server, the same but using `MockMvcWebTestClient`:
[source,java,indent=0,subs="verbatim,quotes"]
----
@@ -76,7 +78,7 @@ For Spring MVC without a server, use the `MockMvcWebTestClient` builder:
WebGraphQlTester tester = WebGraphQlTester.builder(client).build();
----
For tests against a live, running server:
To test against a live, running server:
[source,java,indent=0,subs="verbatim,quotes"]
----