Skip to content

Commit c0707e4

Browse files
committed
Auto-configure GraphQlTester
This commit adds the required infrastructure to auto-configure a `GraphQlTester` or `WebGraphQlTester` in Spring Boot tests. Specific annotations like `AutoConfigureGraphQlTester` and `AutoConfigureWebGraphQlTester` will contribute pre-configured beans for testing a GraphQL with the tester. This also ships a `ContextCustomize` for contributing a `GraphQlTester` in the case of a full `@SpringBootTest` integration test against a live server. See gh-29140
1 parent 9a92a9c commit c0707e4

File tree

16 files changed

+871
-0
lines changed

16 files changed

+871
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.graphql;
18+
19+
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
20+
import org.springframework.core.annotation.MergedAnnotations;
21+
import org.springframework.test.context.TestContextBootstrapper;
22+
23+
/**
24+
* {@link TestContextBootstrapper} for {@link GraphQlTest @GraphQlTest}.
25+
*
26+
* @author Brian Clozel
27+
*/
28+
class GraphQlTestContextBootstrapper extends SpringBootTestContextBootstrapper {
29+
30+
@Override
31+
protected String[] getProperties(Class<?> testClass) {
32+
return MergedAnnotations.from(testClass, MergedAnnotations.SearchStrategy.INHERITED_ANNOTATIONS)
33+
.get(GraphQlTest.class).getValue("properties", String[].class).orElse(null);
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.graphql.tester;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Inherited;
22+
import java.lang.annotation.Retention;
23+
import java.lang.annotation.RetentionPolicy;
24+
import java.lang.annotation.Target;
25+
26+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
27+
import org.springframework.graphql.test.tester.GraphQlTester;
28+
29+
/**
30+
* Annotation that can be applied to a test class to enable a {@link GraphQlTester}.
31+
*
32+
* @author Brian Clozel
33+
* @since 2.7.0
34+
* @see GraphQlTesterAutoConfiguration
35+
*/
36+
@Target({ ElementType.TYPE, ElementType.METHOD })
37+
@Retention(RetentionPolicy.RUNTIME)
38+
@Documented
39+
@Inherited
40+
@ImportAutoConfiguration
41+
public @interface AutoConfigureGraphQlTester {
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.graphql.tester;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Inherited;
22+
import java.lang.annotation.Retention;
23+
import java.lang.annotation.RetentionPolicy;
24+
import java.lang.annotation.Target;
25+
26+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
27+
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
28+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
29+
import org.springframework.graphql.test.tester.WebGraphQlTester;
30+
31+
/**
32+
* Annotation that can be applied to a test class to enable a {@link WebGraphQlTester}.
33+
*
34+
* <p>
35+
* This annotation should be used with
36+
* {@link org.springframework.boot.test.context.SpringBootTest @SpringBootTest} tests with
37+
* Spring MVC or Spring WebFlux mock infrastructures.
38+
*
39+
* @author Brian Clozel
40+
* @since 2.7.0
41+
* @see WebGraphQlTesterAutoConfiguration
42+
*/
43+
@Target({ ElementType.TYPE, ElementType.METHOD })
44+
@Retention(RetentionPolicy.RUNTIME)
45+
@Documented
46+
@Inherited
47+
@AutoConfigureMockMvc
48+
@AutoConfigureWebTestClient
49+
@ImportAutoConfiguration
50+
public @interface AutoConfigureWebGraphQlTester {
51+
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.graphql.tester;
18+
19+
import graphql.GraphQL;
20+
21+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
22+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
25+
import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.graphql.GraphQlService;
29+
import org.springframework.graphql.test.tester.GraphQlTester;
30+
31+
/**
32+
* Auto-configuration for {@link GraphQlTester}.
33+
*
34+
* @author Brian Clozel
35+
* @since 2.7.0
36+
*/
37+
@Configuration(proxyBeanMethods = false)
38+
@ConditionalOnClass({ GraphQL.class, GraphQlTester.class })
39+
@AutoConfigureAfter(GraphQlAutoConfiguration.class)
40+
public class GraphQlTesterAutoConfiguration {
41+
42+
@Bean
43+
@ConditionalOnBean(GraphQlService.class)
44+
@ConditionalOnMissingBean
45+
public GraphQlTester graphQlTester(GraphQlService graphQlService) {
46+
return GraphQlTester.create(graphQlService);
47+
}
48+
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.graphql.tester;
18+
19+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
20+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
21+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
22+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
23+
import org.springframework.boot.autoconfigure.graphql.GraphQlProperties;
24+
import org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration;
25+
import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.graphql.test.tester.WebGraphQlTester;
29+
import org.springframework.test.web.reactive.server.WebTestClient;
30+
import org.springframework.web.reactive.function.client.WebClient;
31+
32+
/**
33+
* Auto-configuration for {@link WebGraphQlTester}.
34+
*
35+
* @author Brian Clozel
36+
* @since 2.7.0
37+
*/
38+
@Configuration(proxyBeanMethods = false)
39+
@ConditionalOnClass({ WebClient.class, WebTestClient.class, WebGraphQlTester.class })
40+
@AutoConfigureAfter({ WebTestClientAutoConfiguration.class, MockMvcAutoConfiguration.class })
41+
public class WebGraphQlTesterAutoConfiguration {
42+
43+
@Bean
44+
@ConditionalOnBean(WebTestClient.class)
45+
@ConditionalOnMissingBean
46+
public WebGraphQlTester webTestClientGraphQlTester(WebTestClient webTestClient, GraphQlProperties properties) {
47+
WebTestClient mutatedWebTestClient = webTestClient.mutate().baseUrl(properties.getPath()).build();
48+
return WebGraphQlTester.create(mutatedWebTestClient);
49+
}
50+
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2020-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Auto-configuration for GraphQL tester.
19+
*/
20+
package org.springframework.boot.test.autoconfigure.graphql.tester;

spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories

+8
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,14 @@ org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
194194
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
195195
org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration
196196

197+
# AutoConfigureGraphQlTester auto-configuration imports
198+
org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester=\
199+
org.springframework.boot.test.autoconfigure.graphql.tester.GraphQlTesterAutoConfiguration
200+
201+
# AutoConfigureWebGraphQlTester auto-configuration imports
202+
org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester=\
203+
org.springframework.boot.test.autoconfigure.graphql.tester.WebGraphQlTesterAutoConfiguration
204+
197205
# AutoConfigureWebServiceClient
198206
org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient=\
199207
org.springframework.boot.test.autoconfigure.webservices.client.WebServiceClientTemplateAutoConfiguration,\
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2012-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.graphql.tester;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.boot.autoconfigure.AutoConfigurations;
22+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
23+
import org.springframework.context.annotation.Bean;
24+
import org.springframework.context.annotation.Configuration;
25+
import org.springframework.graphql.GraphQlService;
26+
import org.springframework.graphql.test.tester.GraphQlTester;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
import static org.mockito.Mockito.mock;
30+
31+
/**
32+
* Tests for {@link GraphQlTesterAutoConfiguration}.
33+
*
34+
* @author Brian Clozel
35+
*/
36+
class GraphQlTesterAutoConfigurationTests {
37+
38+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
39+
.withConfiguration(AutoConfigurations.of(GraphQlTesterAutoConfiguration.class));
40+
41+
@Test
42+
void shouldNotContributeTesterIfGraphQlServiceNotPresent() {
43+
this.contextRunner.run((context) -> assertThat(context).hasNotFailed().doesNotHaveBean(GraphQlTester.class));
44+
}
45+
46+
@Test
47+
void shouldContributeTester() {
48+
this.contextRunner.withUserConfiguration(CustomGraphQlServiceConfiguration.class)
49+
.run((context) -> assertThat(context).hasNotFailed().hasSingleBean(GraphQlTester.class));
50+
}
51+
52+
@Configuration(proxyBeanMethods = false)
53+
static class CustomGraphQlServiceConfiguration {
54+
55+
@Bean
56+
GraphQlService graphQlService() {
57+
return mock(GraphQlService.class);
58+
}
59+
60+
}
61+
62+
}

spring-boot-project/spring-boot-test/build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ dependencies {
3636
optional("org.springframework:spring-test")
3737
optional("org.springframework:spring-web")
3838
optional("org.springframework:spring-webflux")
39+
optional("org.springframework.graphql:spring-graphql-test")
3940
optional("net.sourceforge.htmlunit:htmlunit") {
4041
exclude(group: "commons-logging", module: "commons-logging")
4142
}

0 commit comments

Comments
 (0)