From 3318e81885fa944542ca187b3781fe5296ce8227 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 4 Nov 2021 15:47:51 +0000 Subject: [PATCH] Refactoring in spring-graphql tests Change GraphQlTestUtils to match how tests have evolved with regards to how GraphQlSource is initialized and ensure all tests use it. --- .../springframework/graphql/BookSource.java | 6 + .../graphql/GraphQlTestUtils.java | 59 +++--- .../graphql/TestGraphQlSource.java | 45 ---- .../ArgumentMethodArgumentResolverTests.java | 30 +-- .../support/BatchMappingInvocationTests.java | 17 +- ...chingEnvironmentArgumentResolverTests.java | 27 ++- .../DataLoaderArgumentResolverTests.java | 42 ++-- .../support/SchemaMappingInvocationTests.java | 30 +-- .../querydsl/QuerydslDataFetcherTests.java | 196 ++++++++---------- .../graphql/execution/BatchLoadingTests.java | 44 ++-- .../execution/ClassNameTypeResolverTests.java | 8 +- .../ContextDataFetcherDecoratorTests.java | 49 +++-- .../DefaultBatchLoaderRegistryTests.java | 1 + ...ceptionResolversExceptionHandlerTests.java | 52 ++--- .../graphql/web/BookTestUtils.java | 36 ++-- .../graphql/web/WebGraphQlHandlerTests.java | 71 ++++--- .../web/webflux/GraphQlHttpHandlerTests.java | 7 +- .../web/webmvc/GraphQlHttpHandlerTests.java | 7 +- 18 files changed, 331 insertions(+), 396 deletions(-) delete mode 100644 spring-graphql/src/test/java/org/springframework/graphql/TestGraphQlSource.java diff --git a/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java b/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java index 43e33209..52efe8d2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java @@ -24,8 +24,14 @@ import java.util.stream.Collectors; import reactor.core.publisher.Flux; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + public class BookSource { + public static final Resource schema = new ClassPathResource("books/schema.graphqls"); + + private static final Map booksMap = new HashMap<>(); private static final Map booksWithoutAuthorsMap; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java index 9ca35590..adfe413a 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java @@ -17,16 +17,15 @@ package org.springframework.graphql; import java.nio.charset.StandardCharsets; -import java.util.Arrays; import java.util.Map; import graphql.ExecutionResult; -import graphql.GraphQL; import graphql.schema.DataFetcher; import org.springframework.core.io.ByteArrayResource; -import org.springframework.graphql.execution.DataFetcherExceptionResolver; +import org.springframework.core.io.Resource; import org.springframework.graphql.execution.GraphQlSource; +import org.springframework.graphql.execution.RuntimeWiringConfigurer; import org.springframework.lang.Nullable; import static org.assertj.core.api.Assertions.assertThat; @@ -36,39 +35,49 @@ import static org.assertj.core.api.Assertions.assertThat; */ public abstract class GraphQlTestUtils { - public static GraphQL initGraphQl( - String schemaContent, String typeName, String fieldName, DataFetcher fetcher) { + /** + * Convenience method for a {@link GraphQlSource.Builder} with a single {@link DataFetcher}. + * + * @param schema either String content or a {@link Resource}. + * @param typeName the parent type name (Query, Mutation, or Subscription). + * @param fieldName the name of the operation + * @param fetcher the fetcher to use + * + * @return the created builder + */ + public static GraphQlSource.Builder graphQlSource( + Object schema, String typeName, String fieldName, DataFetcher fetcher) { - return initGraphQlSource(schemaContent, typeName, fieldName, fetcher) - .build() - .graphQl(); + return graphQlSource(schema, + wiring -> wiring.type(typeName, builder -> builder.dataFetcher(fieldName, fetcher))); } - public static GraphQL initGraphQl( - String schemaContent, String typeName, String fieldName, DataFetcher fetcher, - DataFetcherExceptionResolver... resolvers) { - - return initGraphQlSource(schemaContent, typeName, fieldName, fetcher) - .exceptionResolvers(Arrays.asList(resolvers)) - .build() - .graphQl(); - } - - public static GraphQlSource.Builder initGraphQlSource( - String schemaContent, String typeName, String fieldName, DataFetcher fetcher) { + /** + * Convenience method for a {@link GraphQlSource.Builder} when multiple + * {@link DataFetcher} registrations might be needed. + * + * @param schema either String content or a {@link Resource}. + * @param configurer the configurer to apply to the RuntimeWiring + * + * @return the created builder + */ + public static GraphQlSource.Builder graphQlSource(Object schema, RuntimeWiringConfigurer configurer) { + Resource schemaResource = (schema instanceof String ? + new ByteArrayResource(((String) schema).getBytes(StandardCharsets.UTF_8)) : + (Resource) schema); return GraphQlSource.builder() - .schemaResources(new ByteArrayResource(schemaContent.getBytes(StandardCharsets.UTF_8))) - .configureRuntimeWiring(wiring -> wiring.type(typeName, (builder) -> builder.dataFetcher(fieldName, fetcher))); + .schemaResources(schemaResource) + .configureRuntimeWiring(configurer); } @SuppressWarnings("unchecked") - public static T checkErrorsAndGetData(@Nullable ExecutionResult result, String key) { - Map map = checkErrorsAndGetData(result); + public static T getData(@Nullable ExecutionResult result, String key) { + Map map = getData(result); return (T) map.get(key); } - public static T checkErrorsAndGetData(@Nullable ExecutionResult result) { + public static T getData(@Nullable ExecutionResult result) { assertThat(result).isNotNull(); assertThat(result.getErrors()).as("Errors present in GraphQL response").isEmpty(); T data = result.getData(); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/TestGraphQlSource.java b/spring-graphql/src/test/java/org/springframework/graphql/TestGraphQlSource.java deleted file mode 100644 index f7abe9c4..00000000 --- a/spring-graphql/src/test/java/org/springframework/graphql/TestGraphQlSource.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 org.springframework.graphql; - -import graphql.GraphQL; -import graphql.schema.GraphQLSchema; - -import org.springframework.graphql.execution.GraphQlSource; - -/** - * {@link GraphQlSource} that wraps a pre-built {@link GraphQL} instance. - */ -public class TestGraphQlSource implements GraphQlSource { - - private final GraphQL graphQl; - - public TestGraphQlSource(GraphQL graphQl) { - this.graphQl = graphQl; - } - - @Override - public GraphQL graphQl() { - return this.graphQl; - } - - @Override - public GraphQLSchema schema() { - throw new UnsupportedOperationException(); - } - -} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java index 94d6a1d7..2d088990 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.Test; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.format.support.FormattingConversionService; import org.springframework.graphql.Book; import org.springframework.graphql.data.method.annotation.Argument; import org.springframework.graphql.data.method.annotation.MutationMapping; @@ -43,7 +42,6 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link ArgumentMethodArgumentResolver}. - * * @author Brian Clozel */ class ArgumentMethodArgumentResolverTests { @@ -55,24 +53,25 @@ class ArgumentMethodArgumentResolverTests { @Test void shouldSupportAnnotatedParameters() { Method bookById = ClassUtils.getMethod(BookController.class, "bookById", Long.class); - MethodParameter methodParameter = getMethodParameter(bookById, 0); + MethodParameter methodParameter = methodParam(bookById, 0); + assertThat(resolver.supportsParameter(methodParameter)).isTrue(); } @Test void shouldNotSupportParametersWithoutAnnotation() { Method notSupported = ClassUtils.getMethod(BookController.class, "notSupported", String.class); - MethodParameter methodParameter = getMethodParameter(notSupported, 0); + MethodParameter methodParameter = methodParam(notSupported, 0); + assertThat(resolver.supportsParameter(methodParameter)).isFalse(); } @Test void shouldResolveBasicTypeArgument() throws Exception { Method bookById = ClassUtils.getMethod(BookController.class, "bookById", Long.class); - String payload = "{\"id\": 42 }"; - DataFetchingEnvironment environment = initEnvironment(payload); - MethodParameter methodParameter = getMethodParameter(bookById, 0); - Object result = resolver.resolveArgument(methodParameter, environment); + DataFetchingEnvironment environment = initEnvironment("{\"id\": 42 }"); + Object result = resolver.resolveArgument(methodParam(bookById, 0), environment); + assertThat(result).isNotNull().isInstanceOf(Long.class).isEqualTo(42L); } @@ -81,8 +80,8 @@ class ArgumentMethodArgumentResolverTests { Method addBook = ClassUtils.getMethod(BookController.class, "addBook", BookInput.class); String payload = "{\"bookInput\": { \"name\": \"test name\", \"authorId\": 42} }"; DataFetchingEnvironment environment = initEnvironment(payload); - MethodParameter methodParameter = getMethodParameter(addBook, 0); - Object result = resolver.resolveArgument(methodParameter, environment); + Object result = resolver.resolveArgument(methodParam(addBook, 0), environment); + assertThat(result).isNotNull().isInstanceOf(BookInput.class); assertThat((BookInput) result).hasFieldOrPropertyWithValue("name", "test name") .hasFieldOrPropertyWithValue("authorId", 42L); @@ -93,8 +92,8 @@ class ArgumentMethodArgumentResolverTests { Method addBooks = ClassUtils.getMethod(BookController.class, "addBooks", List.class); String payload = "{\"books\": [{ \"name\": \"first\", \"authorId\": 42}, { \"name\": \"second\", \"authorId\": 24}] }"; DataFetchingEnvironment environment = initEnvironment(payload); - MethodParameter methodParameter = getMethodParameter(addBooks, 0); - Object result = resolver.resolveArgument(methodParameter, environment); + Object result = resolver.resolveArgument(methodParam(addBooks, 0), environment); + assertThat(result).isNotNull().isInstanceOf(List.class); assertThat(result).asList().allMatch(item -> item instanceof Book) .extracting("name").containsExactly("first", "second"); @@ -105,13 +104,13 @@ class ArgumentMethodArgumentResolverTests { Method bookByKeyword = ClassUtils.getMethod(BookController.class, "bookByKeyword", Keyword.class); String payload = "{\"keyword\": \"test\" }"; DataFetchingEnvironment environment = initEnvironment(payload); - MethodParameter methodParameter = getMethodParameter(bookByKeyword, 0); - Object result = resolver.resolveArgument(methodParameter, environment); + Object result = resolver.resolveArgument(methodParam(bookByKeyword, 0), environment); + assertThat(result).isNotNull().isInstanceOf(Keyword.class); assertThat((Keyword) result).hasFieldOrPropertyWithValue("term", "test"); } - private MethodParameter getMethodParameter(Method method, int index) { + private MethodParameter methodParam(Method method, int index) { MethodParameter methodParameter = new MethodParameter(method, index); methodParameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); return methodParameter; @@ -122,6 +121,7 @@ class ArgumentMethodArgumentResolverTests { return DataFetchingEnvironmentImpl.newDataFetchingEnvironment().arguments(arguments).build(); } + @Controller static class BookController { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java index 21fd56be..42343e7c 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java @@ -15,7 +15,6 @@ */ package org.springframework.graphql.data.method.annotation.support; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -36,7 +35,6 @@ import reactor.core.publisher.Mono; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.core.io.ByteArrayResource; import org.springframework.graphql.GraphQlService; import org.springframework.graphql.GraphQlTestUtils; import org.springframework.graphql.RequestInput; @@ -121,7 +119,7 @@ public class BatchMappingInvocationTests { .execute(new RequestInput(query, null, null, null)) .block(); - List> actualCourses = GraphQlTestUtils.checkErrorsAndGetData(result, "courses"); + List> actualCourses = GraphQlTestUtils.getData(result, "courses"); List courses = Course.allCourses(); assertThat(actualCourses).hasSize(courses.size()); @@ -153,7 +151,7 @@ public class BatchMappingInvocationTests { .execute(new RequestInput(query, null, null, null)) .block(); - List> actualCourses = GraphQlTestUtils.checkErrorsAndGetData(result, "courses"); + List> actualCourses = GraphQlTestUtils.getData(result, "courses"); List courses = Course.allCourses(); assertThat(actualCourses).hasSize(courses.size()); @@ -253,15 +251,8 @@ public class BatchMappingInvocationTests { private static class CourseConfig { @Bean - public GraphQlSource graphQlSource(AnnotatedControllerConfigurer configurer) { - return GraphQlSource.builder() - .schemaResources(new ByteArrayResource(schema.getBytes(StandardCharsets.UTF_8))) - .configureRuntimeWiring(configurer) - .build(); - } - - @Bean - public GraphQlService graphQlService(GraphQlSource source, BatchLoaderRegistry registry) { + public GraphQlService graphQlService(AnnotatedControllerConfigurer configurer, BatchLoaderRegistry registry) { + GraphQlSource source = GraphQlTestUtils.graphQlSource(schema, configurer).build(); ExecutionGraphQlService service = new ExecutionGraphQlService(source); service.addDataLoaderRegistrar(registry); return service; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java index bd57ace8..17117b7c 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java @@ -57,8 +57,7 @@ public class DataFetchingEnvironmentArgumentResolverTests { @Test void resolveGraphQlContext() { GraphQLContext context = GraphQLContext.newContext().build(); - DataFetchingEnvironment environment = - DataFetchingEnvironmentImpl.newDataFetchingEnvironment().graphQLContext(context).build(); + DataFetchingEnvironment environment = environment().graphQLContext(context).build(); Object actual = this.resolver.resolveArgument(parameter(0), environment); assertThat(actual).isSameAs(context); @@ -67,8 +66,7 @@ public class DataFetchingEnvironmentArgumentResolverTests { @Test void resolveSelectionSet() { DataFetchingFieldSelectionSet selectionSet = mock(DataFetchingFieldSelectionSet.class); - DataFetchingEnvironment environment = - DataFetchingEnvironmentImpl.newDataFetchingEnvironment().selectionSet(selectionSet).build(); + DataFetchingEnvironment environment = environment().selectionSet(selectionSet).build(); Object actual = this.resolver.resolveArgument(parameter(1), environment); assertThat(actual).isSameAs(selectionSet); @@ -77,18 +75,17 @@ public class DataFetchingEnvironmentArgumentResolverTests { @Test void resolveLocale() { Locale locale = Locale.ITALIAN; - DataFetchingEnvironment environment = - DataFetchingEnvironmentImpl.newDataFetchingEnvironment().locale(locale).build(); + DataFetchingEnvironment environment = environment().locale(locale).build(); Object actual = this.resolver.resolveArgument(parameter(2), environment); assertThat(actual).isSameAs(locale); } + @SuppressWarnings("unchecked") @Test void resolveOptionalLocale() { Locale locale = Locale.ITALIAN; - DataFetchingEnvironment environment = - DataFetchingEnvironmentImpl.newDataFetchingEnvironment().locale(locale).build(); + DataFetchingEnvironment environment = environment().locale(locale).build(); Optional actual = (Optional) this.resolver.resolveArgument(parameter(3), environment); assertThat(actual).isNotNull(); @@ -96,14 +93,22 @@ public class DataFetchingEnvironmentArgumentResolverTests { assertThat(actual.get()).isSameAs(locale); } + private static DataFetchingEnvironmentImpl.Builder environment() { + return DataFetchingEnvironmentImpl.newDataFetchingEnvironment(); + } + private MethodParameter parameter(int index) { return new MethodParameter(handleMethod, index); } - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - public void handle(GraphQLContext graphQLContext, DataFetchingFieldSelectionSet selectionSet, - Locale locale, Optional optionalLocale, String s) { + @SuppressWarnings({"OptionalUsedAsFieldOrParameterType", "unused"}) + public void handle( + GraphQLContext graphQLContext, + DataFetchingFieldSelectionSet selectionSet, + Locale locale, + Optional optionalLocale, + String s) { } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java index 5a716537..0a90c8c4 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java @@ -16,7 +16,6 @@ package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; -import java.util.function.Consumer; import graphql.GraphQLContext; import graphql.schema.DataFetchingEnvironment; @@ -38,7 +37,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Unit tests for {@link DataLoaderMethodArgumentResolver}. - * * @author Rossen Stoyanchev */ public class DataLoaderArgumentResolverTests { @@ -48,6 +46,8 @@ public class DataLoaderArgumentResolverTests { private final DataLoaderMethodArgumentResolver resolver = new DataLoaderMethodArgumentResolver(); + private final BatchLoaderRegistry registry = new DefaultBatchLoaderRegistry(); + @Test void supportsParameter() { @@ -57,70 +57,60 @@ public class DataLoaderArgumentResolverTests { @Test void resolveArgument() { + this.registry.forTypePair(Long.class, Author.class).registerBatchLoader((ids, env) -> Flux.empty()); - DataFetchingEnvironment environment = initEnvironment(registry -> - registry.forTypePair(Long.class, Author.class).registerBatchLoader((ids, env) -> Flux.empty())); - - Object argument = this.resolver.resolveArgument(initParameter(0), environment); + Object argument = this.resolver.resolveArgument(initParameter(0), environment()); assertThat(argument).isNotNull(); } @Test void resolveArgumentViaParameterName() { - DataFetchingEnvironment environment = initEnvironment(registry -> - registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty())); + this.registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty()); MethodParameter parameter = initParameter(1); parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); - Object argument = this.resolver.resolveArgument(parameter, environment); + Object argument = this.resolver.resolveArgument(parameter, environment()); assertThat(argument).isNotNull(); } @Test void resolveArgumentFailureWithoutGenericType() { - DataFetchingEnvironment environment = initEnvironment(registry -> - registry.forTypePair(Long.class, Author.class).registerBatchLoader((ids, env) -> Flux.empty())); + this.registry.forTypePair(Long.class, Author.class).registerBatchLoader((ids, env) -> Flux.empty()); - assertThatThrownBy(() -> this.resolver.resolveArgument(initParameter(2), environment)) + assertThatThrownBy(() -> this.resolver.resolveArgument(initParameter(2), environment())) .hasMessageContaining("declaring the DataLoader argument with generic types should help"); } @Test void resolveArgumentFailureWithoutParameterName() { - DataFetchingEnvironment environment = initEnvironment(registry -> - registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty())); + this.registry.forName("namedDataLoader").registerBatchLoader((ids, env) -> Flux.empty()); MethodParameter parameter = initParameter(1); // Skip ParameterNameDiscovery - assertThatThrownBy(() -> this.resolver.resolveArgument(parameter, environment)) + assertThatThrownBy(() -> this.resolver.resolveArgument(parameter, environment())) .hasMessageContaining("compiling with \"-parameters\" should help"); } @Test void resolveArgumentFailureNoMatch() { - DataFetchingEnvironment environment = initEnvironment(registry -> - registry.forName("bookDataLoader").registerBatchLoader((ids, env) -> Flux.empty())); + this.registry.forName("bookDataLoader").registerBatchLoader((ids, env) -> Flux.empty()); MethodParameter parameter = initParameter(0); parameter.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); - assertThatThrownBy(() -> this.resolver.resolveArgument(parameter, environment)) + assertThatThrownBy(() -> this.resolver.resolveArgument(parameter, environment())) .hasMessageContaining( "Neither the name of the declared value type 'class org.springframework.graphql.Author' " + "nor the method parameter name 'authorDataLoader' match to any DataLoader. " + "The DataLoaderRegistry contains: [bookDataLoader]"); } - private DataFetchingEnvironment initEnvironment(Consumer registryConsumer) { - BatchLoaderRegistry batchLoaderRegistry = new DefaultBatchLoaderRegistry(); - registryConsumer.accept(batchLoaderRegistry); - - DataLoaderRegistry registry = DataLoaderRegistry.newRegistry().build(); - batchLoaderRegistry.registerDataLoaders(registry, GraphQLContext.newContext().build()); - - return DataFetchingEnvironmentImpl.newDataFetchingEnvironment().dataLoaderRegistry(registry).build(); + private DataFetchingEnvironment environment() { + DataLoaderRegistry dataLoaderRegistry = DataLoaderRegistry.newRegistry().build(); + this.registry.registerDataLoaders(dataLoaderRegistry, GraphQLContext.newContext().build()); + return DataFetchingEnvironmentImpl.newDataFetchingEnvironment().dataLoaderRegistry(dataLoaderRegistry).build(); } private MethodParameter initParameter(int index) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java index 3b382348..41e1040d 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java @@ -32,7 +32,6 @@ import reactor.test.StepVerifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ClassPathResource; import org.springframework.graphql.Author; import org.springframework.graphql.Book; import org.springframework.graphql.BookCriteria; @@ -77,7 +76,7 @@ public class SchemaMappingInvocationTests { .execute(new RequestInput(query, null, null, null)) .block(); - Map book = GraphQlTestUtils.checkErrorsAndGetData(result, "bookById"); + Map book = GraphQlTestUtils.getData(result, "bookById"); assertThat(book.get("id")).isEqualTo("1"); assertThat(book.get("name")).isEqualTo("Nineteen Eighty-Four"); @@ -99,7 +98,7 @@ public class SchemaMappingInvocationTests { .execute(new RequestInput(query, null, null, null)) .block(); - List> bookList = GraphQlTestUtils.checkErrorsAndGetData(result, "booksByCriteria"); + List> bookList = GraphQlTestUtils.getData(result, "booksByCriteria"); assertThat(bookList).hasSize(2); assertThat(bookList.get(0).get("name")).isEqualTo("Nineteen Eighty-Four"); @@ -127,7 +126,7 @@ public class SchemaMappingInvocationTests { .execute(requestInput) .block(); - Map author = GraphQlTestUtils.checkErrorsAndGetData(result, "authorById"); + Map author = GraphQlTestUtils.getData(result, "authorById"); assertThat(author.get("id")).isEqualTo("101"); assertThat(author.get("firstName")).isEqualTo("George"); @@ -150,7 +149,7 @@ public class SchemaMappingInvocationTests { .execute(new RequestInput(operation, null, null, null)) .block(); - Map author = GraphQlTestUtils.checkErrorsAndGetData(result, "addAuthor"); + Map author = GraphQlTestUtils.getData(result, "addAuthor"); assertThat(author.get("id")).isEqualTo("99"); assertThat(author.get("firstName")).isEqualTo("James"); assertThat(author.get("lastName")).isEqualTo("Joyce"); @@ -169,10 +168,10 @@ public class SchemaMappingInvocationTests { .execute(new RequestInput(operation, null, null, null)) .block(); - Publisher publisher = GraphQlTestUtils.checkErrorsAndGetData(result); + Publisher publisher = GraphQlTestUtils.getData(result); - Flux> bookFlux = Flux.from(publisher).map(rs -> { - Map map = rs.getData(); + Flux> bookFlux = Flux.from(publisher).map(executionResult -> { + Map map = executionResult.getData(); return (Map) map.get("bookSearch"); }); @@ -207,22 +206,15 @@ public class SchemaMappingInvocationTests { } @Bean - public GraphQlService graphQlService(GraphQlSource graphQlSource) { - ExecutionGraphQlService service = new ExecutionGraphQlService(graphQlSource); + public GraphQlService graphQlService(AnnotatedControllerConfigurer configurer) { + GraphQlSource source = GraphQlTestUtils.graphQlSource(BookSource.schema, configurer).build(); + ExecutionGraphQlService service = new ExecutionGraphQlService(source); service.addDataLoaderRegistrar(batchLoaderRegistry()); return service; } @Bean - public GraphQlSource graphQlSource() { - return GraphQlSource.builder() - .schemaResources(new ClassPathResource("books/schema.graphqls")) - .configureRuntimeWiring(annotatedDataFetcherConfigurer()) - .build(); - } - - @Bean - public AnnotatedControllerConfigurer annotatedDataFetcherConfigurer() { + public AnnotatedControllerConfigurer annotatedControllerConfigurer() { return new AnnotatedControllerConfigurer(); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java index 7c096753..8b2ff0c6 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java @@ -19,20 +19,20 @@ package org.springframework.graphql.data.querydsl; import java.net.URI; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.Optional; -import java.util.function.BiConsumer; import java.util.function.Consumer; import com.querydsl.core.types.Predicate; +import graphql.schema.DataFetcher; import graphql.schema.GraphQLTypeVisitor; -import graphql.schema.idl.TypeRuntimeWiring; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.ClassPathResource; import org.springframework.data.keyvalue.core.KeyValueTemplate; import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory; import org.springframework.data.map.MapKeyValueAdapter; @@ -42,9 +42,12 @@ import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.Repository; import org.springframework.graphql.Author; +import org.springframework.graphql.BookSource; +import org.springframework.graphql.GraphQlTestUtils; import org.springframework.graphql.data.GraphQlRepository; import org.springframework.graphql.execution.ExecutionGraphQlService; import org.springframework.graphql.execution.GraphQlSource; +import org.springframework.graphql.execution.RuntimeWiringConfigurer; import org.springframework.graphql.web.WebGraphQlHandler; import org.springframework.graphql.web.WebInput; import org.springframework.graphql.web.WebOutput; @@ -62,32 +65,29 @@ import static org.mockito.Mockito.when; */ class QuerydslDataFetcherTests { - private KeyValueRepositoryFactory repositoryFactory = new KeyValueRepositoryFactory(new KeyValueTemplate(new MapKeyValueAdapter())); - private MockRepository mockRepository = repositoryFactory.getRepository(MockRepository.class); + private final KeyValueRepositoryFactory repositoryFactory = + new KeyValueRepositoryFactory(new KeyValueTemplate(new MapKeyValueAdapter())); + + private final MockRepository mockRepository = repositoryFactory.getRepository(MockRepository.class); + @Test void shouldFetchSingleItems() { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); mockRepository.save(book); - BiConsumer, QuerydslPredicateExecutor> tester = - (wiringConfigurer, executor) -> { - WebGraphQlHandler handler = initWebGraphQlHandler(wiringConfigurer, executor, null); - WebOutput output = handler.handleRequest(input("{ bookById(id: 42) {name}}")).block(); + Consumer tester = (handler) -> { + WebOutput output = handler.handleRequest(input("{ bookById(id: 42) {name}}")).block(); - // TODO: getData interferes with method overrides - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("bookById", - Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy"))); - }; + Map map = GraphQlTestUtils.getData(output, "bookById"); + assertThat(map).hasSize(1).containsEntry("name", book.getName()); + }; // explicit wiring - tester.accept( - builder -> builder.dataFetcher("bookById", QuerydslDataFetcher.builder(mockRepository).single()), - null); + tester.accept(initHandler("bookById", QuerydslDataFetcher.builder(mockRepository).single())); // auto registration - tester.accept(null, mockRepository); + tester.accept(initHandler(builder -> {}, mockRepository, null)); } @Test @@ -96,24 +96,20 @@ class QuerydslDataFetcherTests { Book book2 = new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")); mockRepository.saveAll(Arrays.asList(book1, book2)); - BiConsumer, QuerydslPredicateExecutor> tester = - (wiringConfigurer, executor) -> { - WebGraphQlHandler handler = initWebGraphQlHandler(wiringConfigurer, mockRepository, null); - WebOutput output = handler.handleRequest(input("{ books {name}}")).block(); + Consumer tester = (handler) -> { + WebOutput output = handler.handleRequest(input("{ books {name}}")).block(); - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("books", Arrays.asList( - Collections.singletonMap("name", "Breaking Bad"), - Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy")))); - }; + List> data = GraphQlTestUtils.getData(output, "books"); + assertThat(data).containsExactlyInAnyOrder( + Collections.singletonMap("name", "Breaking Bad"), + Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy")); + }; // explicit wiring - tester.accept( - builder -> builder.dataFetcher("books", QuerydslDataFetcher.builder(mockRepository).many()), - null); + tester.accept(initHandler("books", QuerydslDataFetcher.builder(mockRepository).many())); // auto registration - tester.accept(null, mockRepository); + tester.accept(initHandler(builder -> {}, mockRepository, null)); } @Test @@ -123,21 +119,21 @@ class QuerydslDataFetcherTests { when(mockRepository.findBy(any(), any())).thenReturn(Optional.of(book)); // 1) Automatic registration only - WebGraphQlHandler handler = initWebGraphQlHandler(null, mockRepository, null); + WebGraphQlHandler handler = initHandler(builder -> {}, mockRepository, null); WebOutput output = handler.handleRequest(input("{ bookById(id: 1) {name}}")).block(); - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("bookById", Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy"))); + Map map = GraphQlTestUtils.getData(output, "bookById"); + assertThat(map).hasSize(1).containsEntry("name", "Hitchhiker's Guide to the Galaxy"); // 2) Automatic registration and explicit wiring - handler = initWebGraphQlHandler( - builder -> builder.dataFetcher("bookById", env -> new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg"))), - mockRepository, null); + handler = initHandler( + "bookById", env -> new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")), + mockRepository); output = handler.handleRequest(input("{ bookById(id: 1) {name}}")).block(); - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("bookById", Collections.singletonMap("name", "Breaking Bad"))); + map = GraphQlTestUtils.getData(output, "bookById"); + assertThat(map).hasSize(1).containsEntry("name", "Breaking Bad"); } @Test @@ -145,17 +141,13 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); mockRepository.save(book); - WebGraphQlHandler handler = initWebGraphQlHandler(builder -> builder - .dataFetcher("bookById", QuerydslDataFetcher - .builder(mockRepository) - .projectAs(BookProjection.class) - .single())); + WebGraphQlHandler handler = initHandler("bookById", + QuerydslDataFetcher.builder(mockRepository).projectAs(BookProjection.class).single()); WebOutput output = handler.handleRequest(input("{ bookById(id: 42) {name}}")).block(); - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("bookById", - Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy by Douglas Adams"))); + Map map = GraphQlTestUtils.getData(output, "bookById"); + assertThat(map).hasSize(1).containsEntry("name", "Hitchhiker's Guide to the Galaxy by Douglas Adams"); } @Test @@ -163,29 +155,24 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); mockRepository.save(book); - WebGraphQlHandler handler = initWebGraphQlHandler(builder -> builder - .dataFetcher("bookById", QuerydslDataFetcher - .builder(mockRepository) - .projectAs(BookDto.class) - .single())); + WebGraphQlHandler handler = initHandler("bookById", + QuerydslDataFetcher.builder(mockRepository).projectAs(BookDto.class).single()); WebOutput output = handler.handleRequest(input("{ bookById(id: 42) {name}}")).block(); - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("bookById", - Collections.singletonMap("name", "The book is: Hitchhiker's Guide to the Galaxy"))); + Map map = GraphQlTestUtils.getData(output, "bookById"); + assertThat(map).hasSize(1).containsEntry("name", "The book is: Hitchhiker's Guide to the Galaxy"); } @Test void shouldConstructPredicateProperly() { MockRepository mockRepository = mock(MockRepository.class); - WebGraphQlHandler handler = initWebGraphQlHandler(builder -> builder - .dataFetcher("books", QuerydslDataFetcher - .builder(mockRepository) + WebGraphQlHandler handler = initHandler("books", + QuerydslDataFetcher.builder(mockRepository) .customizer((QuerydslBinderCustomizer) (bindings, book) -> bindings.bind(book.name).firstOptional((path, value) -> value.map(path::startsWith))) - .many())); + .many()); handler.handleRequest(input("{ books(name: \"H\", author: \"Doug\") {name}}")).block(); @@ -202,24 +189,18 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); when(mockRepository.findBy(any(), any())).thenReturn(Mono.just(book)); - BiConsumer, ReactiveQuerydslPredicateExecutor> tester = - (wiringConfigurer, executor) -> { - WebGraphQlHandler handler = initWebGraphQlHandler(wiringConfigurer, null, executor); - WebOutput output = handler.handleRequest(input("{ bookById(id: 1) {name}}")).block(); + Consumer tester = (handler) -> { + WebOutput output = handler.handleRequest(input("{ bookById(id: 1) {name}}")).block(); - // TODO: getData interferes with method overrides - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("bookById", - Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy"))); - }; + Map map = GraphQlTestUtils.getData(output, "bookById"); + assertThat(map).hasSize(1).containsEntry("name", book.getName()); + }; // explicit wiring - tester.accept( - builder -> builder.dataFetcher("bookById", QuerydslDataFetcher.builder(mockRepository).single()), - null); + tester.accept(initHandler("bookById", QuerydslDataFetcher.builder(mockRepository).single())); // auto registration - tester.accept(null, mockRepository); + tester.accept(initHandler(builder -> {}, null, mockRepository)); } @Test @@ -229,24 +210,20 @@ class QuerydslDataFetcherTests { Book book2 = new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")); when(mockRepository.findBy(any(), any())).thenReturn(Flux.just(book1, book2)); - BiConsumer, ReactiveQuerydslPredicateExecutor> tester = - (wiringConfigurer, executor) -> { - WebGraphQlHandler handler = initWebGraphQlHandler(wiringConfigurer, null, mockRepository); - WebOutput output = handler.handleRequest(input("{ books {name}}")).block(); + Consumer tester = (handler) -> { + WebOutput output = handler.handleRequest(input("{ books {name}}")).block(); - assertThat((Object) output.getData()).isEqualTo( - Collections.singletonMap("books", Arrays.asList( - Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy"), - Collections.singletonMap("name", "Breaking Bad")))); - }; + List> data = GraphQlTestUtils.getData(output, "books"); + assertThat(data).containsExactlyInAnyOrder( + Collections.singletonMap("name", "Breaking Bad"), + Collections.singletonMap("name", "Hitchhiker's Guide to the Galaxy")); + }; // explicit wiring - tester.accept( - builder -> builder.dataFetcher("books", QuerydslDataFetcher.builder(mockRepository).many()), - null); + tester.accept(initHandler("books", QuerydslDataFetcher.builder(mockRepository).many())); // auto registration - tester.accept(null, mockRepository); + tester.accept(initHandler(builder -> {}, null, mockRepository)); } @@ -260,49 +237,48 @@ class QuerydslDataFetcherTests { } - static WebGraphQlHandler initWebGraphQlHandler(Consumer configurer) { - return initWebGraphQlHandler(configurer, null, null); + static WebGraphQlHandler initHandler(String fieldName, DataFetcher fetcher) { + return initHandler(fieldName, fetcher, null); } - static WebGraphQlHandler initWebGraphQlHandler( - @Nullable Consumer configurer, + static WebGraphQlHandler initHandler( + String fieldName, DataFetcher fetcher, @Nullable QuerydslPredicateExecutor executor) { + + return initHandler( + GraphQlTestUtils.graphQlSource(BookSource.schema, "Query", fieldName, fetcher), + executor, null); + } + + static WebGraphQlHandler initHandler( + RuntimeWiringConfigurer configurer, @Nullable QuerydslPredicateExecutor executor, @Nullable ReactiveQuerydslPredicateExecutor reactiveExecutor) { - return WebGraphQlHandler - .builder(new ExecutionGraphQlService(graphQlSource(configurer, executor, reactiveExecutor))) - .build(); + return initHandler( + GraphQlTestUtils.graphQlSource(BookSource.schema, configurer), + executor, + reactiveExecutor); } - private static GraphQlSource graphQlSource( - @Nullable Consumer configurer, + private static WebGraphQlHandler initHandler( + GraphQlSource.Builder sourceBuilder, @Nullable QuerydslPredicateExecutor executor, @Nullable ReactiveQuerydslPredicateExecutor reactiveExecutor) { - GraphQlSource.Builder graphQlSourceBuilder = GraphQlSource.builder() - .schemaResources(new ClassPathResource("books/schema.graphqls")); - - if (configurer != null) { - TypeRuntimeWiring.Builder typeBuilder = TypeRuntimeWiring.newTypeWiring("Query"); - configurer.accept(typeBuilder); - graphQlSourceBuilder.configureRuntimeWiring(wiring -> wiring.type(typeBuilder)); - } - GraphQLTypeVisitor visitor = QuerydslDataFetcher.registrationTypeVisitor( (executor != null ? Collections.singletonList(executor) : Collections.emptyList()), - (reactiveExecutor != null ? Collections.singletonList(reactiveExecutor): Collections.emptyList())); + (reactiveExecutor != null ? Collections.singletonList(reactiveExecutor) : Collections.emptyList())); - graphQlSourceBuilder.typeVisitors(Collections.singletonList(visitor)); - - return graphQlSourceBuilder.build(); + GraphQlSource source = sourceBuilder.typeVisitors(Collections.singletonList(visitor)).build(); + ExecutionGraphQlService service = new ExecutionGraphQlService(source); + return WebGraphQlHandler.builder(service).build(); } private WebInput input(String query) { - return new WebInput( - URI.create("http://abc.org"), new HttpHeaders(), Collections.singletonMap("query", query), - null, "1"); + return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), null, "1"); } + interface BookProjection { @Value("#{target.name + ' by ' + target.author.firstName + ' ' + target.author.lastName}") diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java index ea773a51..4272002f 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java @@ -24,10 +24,10 @@ import org.dataloader.DataLoader; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; -import org.springframework.core.io.ClassPathResource; import org.springframework.graphql.Author; import org.springframework.graphql.Book; import org.springframework.graphql.BookSource; +import org.springframework.graphql.GraphQlTestUtils; import org.springframework.graphql.RequestInput; import static org.assertj.core.api.Assertions.assertThat; @@ -40,8 +40,23 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class BatchLoadingTests { + private final BatchLoaderRegistry registry = new DefaultBatchLoaderRegistry(); + + @Test void batchLoader() { + String query = "{ " + + " booksByCriteria(criteria: {author:\"Orwell\"}) { " + + " author {" + + " firstName, " + + " lastName " + + " }" + + " }" + + "}"; + + this.registry.forTypePair(Long.class, Author.class) + .registerBatchLoader((ids, env) -> Flux.fromIterable(ids).map(BookSource::getAuthor)); + ExecutionGraphQlService service = initExecutionGraphQlService(wiring -> { wiring.type("Query", builder -> builder.dataFetcher("booksByCriteria", env -> { Map criteria = env.getArgument("criteria"); @@ -57,23 +72,7 @@ public class BatchLoadingTests { })); }); - BatchLoaderRegistry registry = new DefaultBatchLoaderRegistry(); - registry.forTypePair(Long.class, Author.class) - .registerBatchLoader((ids, env) -> Flux.fromIterable(ids).map(BookSource::getAuthor)); - - service.addDataLoaderRegistrar(registry); - - String query = "{ " + - " booksByCriteria(criteria: {author:\"Orwell\"}) { " + - " author {" + - " firstName, " + - " lastName " + - " }" + - " }" + - "}"; - - RequestInput input = new RequestInput(query, null, null, null); - ExecutionResult result = service.execute(input).block(); + ExecutionResult result = service.execute(new RequestInput(query, null, null, null)).block(); assertThat(result.getErrors()).isEmpty(); Map data = result.getData(); @@ -88,11 +87,10 @@ public class BatchLoadingTests { } private ExecutionGraphQlService initExecutionGraphQlService(RuntimeWiringConfigurer configurer) { - GraphQlSource graphQlSource = GraphQlSource.builder() - .schemaResources(new ClassPathResource("books/schema.graphqls")) - .configureRuntimeWiring(configurer) - .build(); - return new ExecutionGraphQlService(graphQlSource); + GraphQlSource source = GraphQlTestUtils.graphQlSource(BookSource.schema, configurer).build(); + ExecutionGraphQlService service = new ExecutionGraphQlService(source); + service.addDataLoaderRegistrar(this.registry); + return service; } @SuppressWarnings("unchecked") diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java index 1435889b..40e61fa2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java @@ -67,7 +67,7 @@ public class ClassNameTypeResolverTests { void typeResolutionViaSuperHierarchy() { GraphQlSource graphQlSource = - GraphQlTestUtils.initGraphQlSource(schema, "Query", "animals", env -> animalList).build(); + GraphQlTestUtils.graphQlSource(schema, "Query", "animals", env -> animalList).build(); String query = "" + "query Animals {" + @@ -87,7 +87,7 @@ public class ClassNameTypeResolverTests { .execute(new RequestInput(query, null, null, null)) .block(); - List> actualAnimals = GraphQlTestUtils.checkErrorsAndGetData(result, "animals"); + List> actualAnimals = GraphQlTestUtils.getData(result, "animals"); for (int i = 0; i < animalList.size(); i++) { Map actualAnimal = actualAnimals.get(i); @@ -113,7 +113,7 @@ public class ClassNameTypeResolverTests { typeResolver.addMapping(Tree.class, "Plant"); GraphQlSource graphQlSource = - GraphQlTestUtils.initGraphQlSource(schema, "Query", "sightings", env -> animalAndPlantList) + GraphQlTestUtils.graphQlSource(schema, "Query", "sightings", env -> animalAndPlantList) .defaultTypeResolver(typeResolver) .build(); @@ -137,7 +137,7 @@ public class ClassNameTypeResolverTests { .execute(new RequestInput(query, null, null, null)) .block(); - List> actualSightings = GraphQlTestUtils.checkErrorsAndGetData(result, "sightings"); + List> actualSightings = GraphQlTestUtils.getData(result, "sightings"); for (int i = 0; i < animalAndPlantList.size(); i++) { Map actualSighting = actualSightings.get(i); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java index 1a3c9913..334f3298 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java @@ -23,6 +23,7 @@ import java.util.Map; import graphql.ExecutionInput; import graphql.ExecutionResult; import graphql.GraphQL; +import graphql.schema.DataFetcher; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -37,13 +38,15 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link ContextDataFetcherDecorator}. + * @author Rossen Stoyanchev */ public class ContextDataFetcherDecoratorTests { @Test void monoDataFetcher() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> Mono.deferContextual((context) -> { + GraphQL graphQl = initGraphQl( + "type Query { greeting: String }", + "Query", "greeting", (env) -> Mono.deferContextual((context) -> { Object name = context.get("name"); return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name); })); @@ -58,25 +61,29 @@ public class ContextDataFetcherDecoratorTests { @Test void fluxDataFetcher() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greetings: [String] }", "Query", "greetings", - (env) -> Mono.delay(Duration.ofMillis(50)).flatMapMany((aLong) -> Flux.deferContextual((context) -> { - String name = context.get("name"); - return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); - }))); + GraphQL graphQl = initGraphQl( + "type Query { greetings: [String] }", + "Query", "greetings", + (env) -> Mono.delay(Duration.ofMillis(50)) + .flatMapMany((aLong) -> Flux.deferContextual((context) -> { + String name = context.get("name"); + return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); + }))); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greetings }").build(); ReactorContextManager.setReactorContext(Context.of("name", "007"), input); - Map data = graphQl.executeAsync(input).get().getData(); + ExecutionResult result = graphQl.executeAsync(input).get(); - assertThat((List) data.get("greetings")).containsExactly("Hi 007", "Bonjour 007", "Hola 007"); + List data = GraphQlTestUtils.getData(result, "greetings"); + assertThat(data).containsExactly("Hi 007", "Bonjour 007", "Hola 007"); } @Test void fluxDataFetcherSubscription() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl( - "type Query { greeting: String } type Subscription { greetings: String }", "Subscription", "greetings", - (env) -> Mono.delay(Duration.ofMillis(50)) + GraphQL graphQl = initGraphQl( + "type Query { greeting: String } type Subscription { greetings: String }", + "Subscription", "greetings", (env) -> Mono.delay(Duration.ofMillis(50)) .flatMapMany((aLong) -> Flux.deferContextual((context) -> { String name = context.get("name"); return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); @@ -88,8 +95,7 @@ public class ContextDataFetcherDecoratorTests { Publisher publisher = graphQl.executeAsync(input).get().getData(); List actual = Flux.from(publisher).cast(ExecutionResult.class) - .map((result) -> ((Map) result.getData()).get("greetings")) - .cast(String.class) + .map((result) -> GraphQlTestUtils.getData(result, "greetings")) .collectList() .block(); @@ -102,9 +108,9 @@ public class ContextDataFetcherDecoratorTests { nameThreadLocal.set("007"); TestThreadLocalAccessor accessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQL graphQl = GraphQlTestUtils.initGraphQl( - "type Query { greeting: String }", "Query", "greeting", - (env) -> "Hello " + nameThreadLocal.get()); + GraphQL graphQl = initGraphQl( + "type Query { greeting: String }", + "Query", "greeting", (env) -> "Hello " + nameThreadLocal.get()); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ContextView view = ReactorContextManager.extractThreadLocalValues(accessor, Context.empty()); @@ -114,7 +120,7 @@ public class ContextDataFetcherDecoratorTests { .flatMap((aLong) -> Mono.fromFuture(graphQl.executeAsync(input))) .block(); - Map data = result.getData(); + Map data = GraphQlTestUtils.getData(result); assertThat(data).hasSize(1).containsEntry("greeting", "Hello 007"); } finally { @@ -122,4 +128,11 @@ public class ContextDataFetcherDecoratorTests { } } + private static GraphQL initGraphQl( + String schemaContent, String typeName, String fieldName, DataFetcher fetcher) { + + return GraphQlTestUtils.graphQlSource(schemaContent, typeName, fieldName, fetcher) + .build().graphQl(); + } + } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java index 9b853ec2..c3d0bfc2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; /** * Unit tests for {@link DefaultBatchLoaderRegistry}. + * @author Rossen Stoyanchev */ public class DefaultBatchLoaderRegistryTests { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java index 343d872a..095294b2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java @@ -40,16 +40,14 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link ExceptionResolversExceptionHandler}. + * @author Rossen Stoyanchev */ public class ExceptionResolversExceptionHandlerTests { @Test void resolveException() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }, - (ex, env) -> Mono.just(Collections.singletonList( + GraphQL graphQl = initGraphQl((ex, env) -> + Mono.just(Collections.singletonList( GraphqlErrorBuilder.newError(env) .message("Resolved error: " + ex.getMessage()) .errorType(ErrorType.BAD_REQUEST).build()))); @@ -68,11 +66,8 @@ public class ExceptionResolversExceptionHandlerTests { @Test void resolveExceptionWithReactorContext() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }, - (ex, env) -> Mono.deferContextual((view) -> Mono.just(Collections.singletonList( + GraphQL graphQl = initGraphQl((ex, env) -> + Mono.deferContextual((view) -> Mono.just(Collections.singletonList( GraphqlErrorBuilder.newError(env) .message("Resolved error: " + ex.getMessage() + ", name=" + view.get("name")) .errorType(ErrorType.BAD_REQUEST).build())))); @@ -92,15 +87,11 @@ public class ExceptionResolversExceptionHandlerTests { nameThreadLocal.set("007"); TestThreadLocalAccessor accessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }, - threadLocalContextAwareExceptionResolver((ex, env) -> - GraphqlErrorBuilder.newError(env) - .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) - .errorType(ErrorType.BAD_REQUEST) - .build())); + GraphQL graphQl = initGraphQl(threadLocalContextAwareExceptionResolver((ex, env) -> + GraphqlErrorBuilder.newError(env) + .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) + .errorType(ErrorType.BAD_REQUEST) + .build())); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ContextView view = ReactorContextManager.extractThreadLocalValues(accessor, Context.empty()); @@ -120,11 +111,7 @@ public class ExceptionResolversExceptionHandlerTests { @Test void unresolvedException() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }, - (exception, environment) -> Mono.empty()); + GraphQL graphQl = initGraphQl((exception, environment) -> Mono.empty()); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ExecutionResult result = graphQl.executeAsync(input).get(); @@ -141,11 +128,7 @@ public class ExceptionResolversExceptionHandlerTests { @Test void suppressedException() throws Exception { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }, - (ex, env) -> Mono.just(Collections.emptyList())); + GraphQL graphQl = initGraphQl((ex, env) -> Mono.just(Collections.emptyList())); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ExecutionResult result = graphQl.executeAsync(input).get(); @@ -155,6 +138,17 @@ public class ExceptionResolversExceptionHandlerTests { assertThat(result.getErrors()).hasSize(0); } + private static GraphQL initGraphQl(DataFetcherExceptionResolver exceptionResolver) { + return GraphQlTestUtils.graphQlSource( + "type Query { greeting: String }", + "Query", "greeting", (env) -> { + throw new IllegalArgumentException("Invalid greeting"); + }) + .exceptionResolvers(Collections.singletonList(exceptionResolver)) + .build() + .graphQl(); + } + private static DataFetcherExceptionResolver threadLocalContextAwareExceptionResolver( BiFunction resolver) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java b/spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java index f803f91f..34c2660e 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java @@ -18,11 +18,10 @@ package org.springframework.graphql.web; import java.util.Arrays; -import graphql.schema.idl.TypeRuntimeWiring; import reactor.core.publisher.Flux; -import org.springframework.core.io.ClassPathResource; import org.springframework.graphql.BookSource; +import org.springframework.graphql.GraphQlTestUtils; import org.springframework.graphql.execution.ExecutionGraphQlService; import org.springframework.graphql.execution.GraphQlSource; @@ -61,26 +60,23 @@ public abstract class BookTestUtils { "}"; public static WebGraphQlHandler initWebGraphQlHandler(WebInterceptor... interceptors) { - return WebGraphQlHandler.builder(new ExecutionGraphQlService(graphQlSource())) + + GraphQlSource source = GraphQlTestUtils.graphQlSource(BookSource.schema, + wiringBuilder -> { + wiringBuilder.type("Query", builder -> builder.dataFetcher("bookById", (env) -> { + Long id = Long.parseLong(env.getArgument("id")); + return BookSource.getBook(id); + })); + wiringBuilder.type("Subscription", builder -> builder.dataFetcher("bookSearch", (env) -> { + String author = env.getArgument("author"); + return Flux.fromIterable(BookSource.books()) + .filter((book) -> book.getAuthor().getFullName().contains(author)); + })); + }).build(); + + return WebGraphQlHandler.builder(new ExecutionGraphQlService(source)) .interceptors(Arrays.asList(interceptors)) .build(); } - private static GraphQlSource graphQlSource() { - return GraphQlSource.builder() - .schemaResources(new ClassPathResource("books/schema.graphqls")) - .configureRuntimeWiring(builder -> builder.type(TypeRuntimeWiring.newTypeWiring("Query") - .dataFetcher("bookById", (env) -> { - Long id = Long.parseLong(env.getArgument("id")); - return BookSource.getBook(id); - })) - .type(TypeRuntimeWiring.newTypeWiring("Subscription") - .dataFetcher("bookSearch", (env) -> { - String author = env.getArgument("author"); - return Flux.fromIterable(BookSource.books()) - .filter((book) -> book.getAuthor().getFullName().contains(author)); - }))) - .build(); - } - } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java index c114f0e1..94104f03 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.function.BiFunction; -import graphql.GraphQL; import graphql.GraphQLError; import graphql.GraphqlErrorBuilder; import graphql.schema.DataFetchingEnvironment; @@ -32,12 +31,12 @@ import reactor.core.publisher.Mono; import org.springframework.graphql.GraphQlService; import org.springframework.graphql.GraphQlTestUtils; -import org.springframework.graphql.TestGraphQlSource; import org.springframework.graphql.TestThreadLocalAccessor; import org.springframework.graphql.execution.DataFetcherExceptionResolver; import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter; import org.springframework.graphql.execution.ErrorType; import org.springframework.graphql.execution.ExecutionGraphQlService; +import org.springframework.graphql.execution.GraphQlSource; import org.springframework.http.HttpHeaders; import static org.assertj.core.api.Assertions.assertThat; @@ -53,17 +52,18 @@ public class WebGraphQlHandlerTests { @Test void reactorContextPropagation() { - GraphQL graphQl = GraphQlTestUtils.initGraphQl( - "type Query { greeting: String }", "Query", "greeting", - (env) -> Mono.deferContextual((context) -> { + GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( + "type Query { greeting: String }", + "Query", "greeting", (env) -> Mono.deferContextual((context) -> { Object name = context.get("name"); return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name); - })); + })).build(); - GraphQlService service = new ExecutionGraphQlService(new TestGraphQlSource(graphQl)); + GraphQlService service = new ExecutionGraphQlService(graphQlSource); WebGraphQlHandler handler = WebGraphQlHandler.builder(service).build(); - WebOutput webOutput = handler.handleRequest(webInput).contextWrite((context) -> context.put("name", "007")).block(); + WebOutput webOutput = handler.handleRequest(webInput) + .contextWrite((context) -> context.put("name", "007")).block(); Map data = webOutput.getData(); assertThat(data).hasSize(1).containsEntry("greeting", "Hello 007"); @@ -71,19 +71,25 @@ public class WebGraphQlHandlerTests { @Test void reactorContextPropagationToExceptionResolver() { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }, - (ex, env) -> Mono.deferContextual((view) -> Mono.just(Collections.singletonList( - GraphqlErrorBuilder - .newError(env).message("Resolved error: " + ex.getMessage() + ", name=" + view.get("name")) - .errorType(ErrorType.BAD_REQUEST).build())))); - GraphQlService service = new ExecutionGraphQlService(new TestGraphQlSource(graphQl)); + GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( + "type Query { greeting: String }", + "Query", "greeting", (env) -> { + throw new IllegalArgumentException("Invalid greeting"); + }) + .exceptionResolvers(Collections.singletonList( + (ex, env) -> Mono.deferContextual((view) -> Mono.just(Collections.singletonList( + GraphqlErrorBuilder.newError(env) + .message("Resolved error: " + ex.getMessage() + ", name=" + view.get("name")) + .errorType(ErrorType.BAD_REQUEST) + .build()))))) + .build(); + + GraphQlService service = new ExecutionGraphQlService(graphQlSource); WebGraphQlHandler handler = WebGraphQlHandler.builder(service).build(); - WebOutput webOutput = handler.handleRequest(webInput).contextWrite((context) -> context.put("name", "007")).block(); + WebOutput webOutput = handler.handleRequest(webInput) + .contextWrite((context) -> context.put("name", "007")).block(); Map data = webOutput.getData(); assertThat(data).hasSize(1).containsEntry("greeting", null); @@ -99,11 +105,12 @@ public class WebGraphQlHandlerTests { nameThreadLocal.set("007"); TestThreadLocalAccessor threadLocalAccessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQL graphQl = GraphQlTestUtils.initGraphQl( - "type Query { greeting: String }", "Query", "greeting", - (env) -> "Hello " + nameThreadLocal.get()); + GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( + "type Query { greeting: String }", + "Query", "greeting", env -> "Hello " + nameThreadLocal.get()) + .build(); - GraphQlService service = new ExecutionGraphQlService(new TestGraphQlSource(graphQl)); + GraphQlService service = new ExecutionGraphQlService(graphQlSource); WebGraphQlHandler handler = WebGraphQlHandler.builder(service) .interceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input))) @@ -125,16 +132,20 @@ public class WebGraphQlHandlerTests { nameThreadLocal.set("007"); TestThreadLocalAccessor threadLocalAccessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQL graphQl = GraphQlTestUtils.initGraphQl("type Query { greeting: String }", "Query", "greeting", - (env) -> { + GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( + "type Query { greeting: String }", + "Query", "greeting", env -> { throw new IllegalArgumentException("Invalid greeting"); - }, - threadLocalContextAwareExceptionResolver((ex, env) -> - GraphqlErrorBuilder.newError(env) - .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) - .errorType(ErrorType.BAD_REQUEST).build())); + }) + .exceptionResolvers(Collections.singletonList( + threadLocalContextAwareExceptionResolver((ex, env) -> + GraphqlErrorBuilder.newError(env) + .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) + .errorType(ErrorType.BAD_REQUEST).build()) + )) + .build(); - GraphQlService service = new ExecutionGraphQlService(new TestGraphQlSource(graphQl)); + GraphQlService service = new ExecutionGraphQlService(graphQlSource); WebGraphQlHandler handler = WebGraphQlHandler.builder(service) .interceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input))) diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java index 539040fe..8bc21ecb 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java @@ -20,15 +20,14 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import graphql.GraphQL; import graphql.schema.DataFetcher; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import org.springframework.graphql.GraphQlService; import org.springframework.graphql.GraphQlTestUtils; -import org.springframework.graphql.TestGraphQlSource; import org.springframework.graphql.execution.ExecutionGraphQlService; +import org.springframework.graphql.execution.GraphQlSource; import org.springframework.graphql.web.WebGraphQlHandler; import org.springframework.http.codec.EncoderHttpMessageWriter; import org.springframework.http.codec.HttpMessageWriter; @@ -68,8 +67,8 @@ public class GraphQlHttpHandlerTests { private GraphQlHttpHandler createHttpHandler( String schemaContent, String type, String field, DataFetcher dataFetcher) { - GraphQL graphQl = GraphQlTestUtils.initGraphQl(schemaContent, type, field, dataFetcher); - GraphQlService service = new ExecutionGraphQlService(new TestGraphQlSource(graphQl)); + GraphQlSource source = GraphQlTestUtils.graphQlSource(schemaContent, type, field, dataFetcher).build(); + GraphQlService service = new ExecutionGraphQlService(source); return new GraphQlHttpHandler(WebGraphQlHandler.builder(service).build()); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java index c734409b..ac3e4a3c 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java @@ -23,15 +23,14 @@ import java.util.Locale; import javax.servlet.ServletException; -import graphql.GraphQL; import graphql.schema.DataFetcher; import org.junit.jupiter.api.Test; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.graphql.GraphQlService; import org.springframework.graphql.GraphQlTestUtils; -import org.springframework.graphql.TestGraphQlSource; import org.springframework.graphql.execution.ExecutionGraphQlService; +import org.springframework.graphql.execution.GraphQlSource; import org.springframework.graphql.web.WebGraphQlHandler; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -78,8 +77,8 @@ public class GraphQlHttpHandlerTests { private GraphQlHttpHandler createHttpHandler( String schemaContent, String type, String field, DataFetcher dataFetcher) { - GraphQL graphQl = GraphQlTestUtils.initGraphQl(schemaContent, type, field, dataFetcher); - GraphQlService service = new ExecutionGraphQlService(new TestGraphQlSource(graphQl)); + GraphQlSource source = GraphQlTestUtils.graphQlSource(schemaContent, type, field, dataFetcher).build(); + GraphQlService service = new ExecutionGraphQlService(source); return new GraphQlHttpHandler(WebGraphQlHandler.builder(service).build()); }