Spring for GraphQL 为通过 HTTP 测试 GraphQL 请求提供了专门的支持, WebSocket 和 RSocket,以及直接针对服务器进行测试。Spring中文文档

要利用此功能,请添加到您的构建中:spring-graphql-testSpring中文文档

dependencies {
	// ...
	testImplementation 'org.springframework.graphql:spring-graphql-test:1.3.1'
}
<dependencies>
	<!-- ... -->
	<dependency>
		<groupId>org.springframework.graphql</groupId>
		<artifactId>spring-graphql-test</artifactId>
		<version>1.3.1</version>
		<scope>test</scope>
	</dependency>
</dependencies>

GraphQlTester

GraphQlTester是一个声明用于测试 GraphQL 的通用工作流的协定 独立于基础传输的请求。这意味着请求会经过测试 使用相同的 API,无论底层传输是什么,以及任何传输 特定是在生成时配置的。Spring中文文档

要创建通过客户端执行请求的 以下扩展:GraphQlTesterSpring中文文档

要创建在服务器端执行测试(不带客户端)的测试,请执行以下操作:GraphQlTesterSpring中文文档

每个定义一个与传输相关的选项。所有构建器扩展 来自一个普通的、基本的 GraphQlTester Builder 与所有扩展相关的选项。BuilderSpring中文文档

HTTP的

HttpGraphQlTester使用 WebTestClient 执行 GraphQL 通过 HTTP 请求,有或没有实时服务器,具体取决于配置方式。WebTestClientSpring中文文档

要在没有实时服务器的情况下在 Spring WebFlux 中进行测试,请指向您的 Spring 配置 声明 GraphQL HTTP 端点:Spring中文文档

ApplicationContext context = ... ;

WebTestClient client =
		WebTestClient.bindToApplicationContext(context)
				.configureClient()
				.baseUrl("/graphql")
				.build();

HttpGraphQlTester tester = HttpGraphQlTester.create(client);

要在没有实时服务器的情况下在 Spring MVC 中进行测试,请使用以下命令执行相同的操作:MockMvcWebTestClientSpring中文文档

ApplicationContext context = ... ;

WebTestClient client =
		MockMvcWebTestClient.bindToApplicationContext(context)
				.configureClient()
				.baseUrl("/graphql")
				.build();

HttpGraphQlTester tester = HttpGraphQlTester.create(client);

或者针对端口上运行的实时服务器进行测试:Spring中文文档

WebTestClient client =
		WebTestClient.bindToServer()
				.baseUrl("http://localhost:8080/graphql")
				.build();

HttpGraphQlTester tester = HttpGraphQlTester.create(client);

创建后,您可以开始使用相同的 API 执行请求,而与基础无关 运输。如果您需要更改任何传输特定的详细信息,请在 existing 创建具有自定义设置的新实例:HttpGraphQlTestermutate()HttpSocketGraphQlTesterSpring中文文档

HttpGraphQlTester tester = HttpGraphQlTester.builder(clientBuilder)
		.headers(headers -> headers.setBasicAuth("joe", "..."))
		.build();

// Use tester...

HttpGraphQlTester anotherTester = tester.mutate()
		.headers(headers -> headers.setBasicAuth("peter", "..."))
		.build();

// Use anotherTester...

网络套接字

WebSocketGraphQlTester通过共享 WebSocket 连接执行 GraphQL 请求。 它是使用 Spring WebFlux 中的 WebSocketClient 构建的,您可以按如下方式创建它:Spring中文文档

String url = "http://localhost:8080/graphql";
WebSocketClient client = new ReactorNettyWebSocketClient();

WebSocketGraphQlTester tester = WebSocketGraphQlTester.builder(url, client).build();

WebSocketGraphQlTester是面向连接和多路复用的。每个实例建立 它自己的单个共享连接用于所有请求。通常,您需要使用单个 仅每个服务器的实例。Spring中文文档

创建后,您可以开始使用相同的 API 执行请求,而与基础无关 运输。如果您需要更改任何传输特定的详细信息,请在 existing 创建具有自定义设置的新实例:WebSocketGraphQlTestermutate()WebSocketGraphQlTesterSpring中文文档

URI url = ... ;
WebSocketClient client = ... ;

WebSocketGraphQlTester tester = WebSocketGraphQlTester.builder(url, client)
		.headers(headers -> headers.setBasicAuth("joe", "..."))
		.build();

// Use tester...

WebSocketGraphQlTester anotherTester = tester.mutate()
		.headers(headers -> headers.setBasicAuth("peter", "..."))
		.build();

// Use anotherTester...

WebSocketGraphQlTester提供了可用于拥有 WebSocket 的方法 连接关闭,例如在测试运行后。stop()Spring中文文档

RSocket

RSocketGraphQlTester使用 from spring-messaging 执行 GraphQL 通过 RSocket 发出的请求:RSocketRequesterSpring中文文档

URI uri = URI.create("wss://localhost:8080/rsocket");
WebsocketClientTransport transport = WebsocketClientTransport.create(url);

RSocketGraphQlTester client = RSocketGraphQlTester.builder()
		.clientTransport(transport)
		.build();

RSocketGraphQlTester是面向连接和多路复用的。每个实例建立 它自己的单个共享会话用于所有请求。通常,您需要使用单个 仅每个服务器的实例。您可以使用测试仪上的方法关闭 会话显式。stop()Spring中文文档

创建后,您可以开始使用相同的 API 执行请求,而与基础无关 运输。RSocketGraphQlTesterSpring中文文档

ExecutionGraphQlService

很多时候,在服务器端测试 GraphQL 请求就足够了,而无需使用 客户端通过传输协议发送请求。要直接针对 进行测试,请使用扩展:ExecutionGraphQlServiceExecutionGraphQlServiceTesterSpring中文文档

ExecutionGraphQlService service = ... ;
ExecutionGraphQlServiceTester tester = ExecutionGraphQlServiceTester.create(service);

创建后,您可以开始使用相同的 API 执行请求,而与基础无关 运输。ExecutionGraphQlServiceTesterSpring中文文档

ExecutionGraphQlServiceTester.Builder提供了自定义详细信息的选项:ExecutionInputSpring中文文档

ExecutionGraphQlService service = ... ;
ExecutionGraphQlServiceTester tester = ExecutionGraphQlServiceTester.builder(service)
		.configureExecutionInput((executionInput, builder) -> builder.executionId(id).build())
		.build();

WebGraphQlHandler

ExecutionGraphQlService 扩展允许您在服务器端进行测试,而无需 客户端。但是,在某些情况下,涉及服务器端传输很有用 使用给定的模拟传输输入进行处理。Spring中文文档

该扩展允许您在移交给 for 之前通过链处理请求 请求执行:WebGraphQlTesterWebGraphQlInterceptorExecutionGraphQlServiceSpring中文文档

WebGraphQlHandler handler = ... ;
WebGraphQlTester tester = WebGraphQlTester.create(handler);

此扩展的构建器允许您定义 HTTP 请求详细信息:Spring中文文档

WebGraphQlHandler handler = ... ;

WebGraphQlTester tester = WebGraphQlTester.builder(handler)
		.headers(headers -> headers.setBasicAuth("joe", "..."))
		.build();

创建后,您可以开始使用相同的 API 执行请求,而与基础传输无关。WebGraphQlTesterSpring中文文档

建筑工人

GraphQlTester定义一个父级,其中包含 所有扩展的构建者。它允许您配置以下内容:BuilderSpring中文文档

  • errorFilter- 一个用于抑制预期错误的谓词,以便您可以检查数据 的响应。Spring中文文档

  • documentSource- 从文件加载文档以请求的策略 类路径或来自其他任何位置。Spring中文文档

  • responseTimeout- 在计时之前等待请求执行完成多长时间 外。Spring中文文档

请求

一旦你有了 ,你就可以开始测试请求了。下面执行一个 查询项目并使用 JsonPath 提取 响应中的项目发布版本:GraphQlTesterSpring中文文档

String document = "{" +
		"  project(slug:\"spring-framework\") {" +
		"	releases {" +
		"	  version" +
		"	}"+
		"  }" +
		"}";

graphQlTester.document(document)
		.execute()
		.path("project.releases[*].version")
		.entityList(String.class)
		.hasSizeGreaterThan(1);

JsonPath 相对于响应的“数据”部分。Spring中文文档

您还可以在类路径上创建扩展名或以下的文档文件,并按文件名引用它们。.graphql.gql"graphql-test/"Spring中文文档

例如,给定一个名为 的文件,其中包含 的内容:projectReleases.graphqlsrc/main/resources/graphql-testSpring中文文档

query projectReleases($slug: ID!) {
	project(slug: $slug) {
		releases {
			version
		}
	}
}

然后,您可以使用:Spring中文文档

graphQlTester.documentName("projectReleases") (1)
		.variable("slug", "spring-framework") (2)
		.execute()
		.path("project.releases[*].version")
		.entityList(String.class)
		.hasSizeGreaterThan(1);
1 请参阅名为“project”的文件中的文档。
2 设置变量。slug

IntelliJ 的“JS GraphQL”插件支持具有代码完成的 GraphQL 查询文件。Spring中文文档

如果请求没有任何响应数据,例如 mutation,请使用 instead of 来验证响应中没有错误:executeAndVerifyexecuteSpring中文文档

graphQlTester.query(query).executeAndVerify();

有关错误处理的更多详细信息,请参阅错误Spring中文文档

嵌套路径

默认情况下,路径相对于 GraphQL 响应的“数据”部分。您还可以 嵌套到路径,并检查与其相关的多条路径,如下所示:Spring中文文档

graphQlTester.document(document)
		.execute()
		.path("project", project -> project (1)
			.path("name").entity(String.class).isEqualTo("spring-framework")
			.path("releases[*].version").entityList(String.class).hasSizeGreaterThan(1));
1 使用回调检查相对于“project”的路径。
1 请参阅名为“project”的文件中的文档。
2 设置变量。slug

IntelliJ 的“JS GraphQL”插件支持具有代码完成的 GraphQL 查询文件。Spring中文文档

1 使用回调检查相对于“project”的路径。

订阅

若要测试订阅,请调用而不是获取流 的响应,然后使用来自 Project Reactor 来检查流:executeSubscriptionexecuteStepVerifierSpring中文文档

Flux<String> greetingFlux = tester.document("subscription { greetings }")
		.executeSubscription()
		.toFlux("greetings", String.class);  // decode at JSONPath

StepVerifier.create(greetingFlux)
		.expectNext("Hi")
		.expectNext("Bonjour")
		.expectNext("Hola")
		.verifyComplete();

错误

当您使用 时,响应中“errors”键下的任何错误都会导致 断言失败。要禁止显示特定错误,请在以下情况下使用错误过滤器:verify()verify()Spring中文文档

graphQlTester.query(query)
		.execute()
		.errors()
		.filter(error -> ...)
		.verify()
		.path("project.releases[*].version")
		.entityList(String.class)
		.hasSizeGreaterThan(1);

您可以在生成器级别注册错误筛选器,以应用于所有测试:Spring中文文档

WebGraphQlTester graphQlTester = WebGraphQlTester.builder(client)
		.errorFilter(error -> ...)
		.build();

如果要验证错误是否确实存在,并且与 相反,请抛出 断言错误,如果没有,则改用:filterexpectSpring中文文档

graphQlTester.query(query)
		.execute()
		.errors()
		.expect(error -> ...)
		.verify()
		.path("project.releases[*].version")
		.entityList(String.class)
		.hasSizeGreaterThan(1);

您还可以通过 检查所有错误,这样做也会将它们标记为 筛选,因此您还可以检查响应中的数据:ConsumerSpring中文文档

graphQlTester.query(query)
		.execute()
		.errors()
		.satisfy(errors -> {
			// ...
		});