10. 测试
Spring for GraphQL 为通过 HTTP 测试 GraphQL 请求提供专用支持, WebSocket 和 RSocket,以及直接针对服务器进行测试。
要使用此功能,请添加到您的构建中:spring-graphql-test
dependencies {
// ...
testImplementation 'org.springframework.graphql:spring-graphql-test:1.1.7'
}
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<version>1.1.7</version>
<scope>test</scope>
</dependency>
</dependencies>
10.1.GraphQlTester
GraphQlTester
是一个声明用于测试 GraphQL 的通用工作流程的合同
请求,该请求独立于底层传输。这意味着请求已经过测试
使用相同的 API,无论底层传输是什么,以及任何传输
specific 在构建时进行配置。
要创建通过客户端执行请求的 ,您需要
以下扩展名:GraphQlTester
要创建在服务器端执行测试的 a,而无需客户端:GraphQlTester
每个 define a 都包含与传输相关的选项。所有构建器都扩展了
来自一个常见的、基本的 GraphQlTester Builder
中,具有
与所有扩展相关的选项。Builder
10.1.1. HTTP 协议
HttpGraphQlTester
使用 WebTestClient 执行
通过 HTTP 发出的 GraphQL 请求,无论是否有实时服务器,具体取决于配置方式。WebTestClient
要在 Spring WebFlux 中进行测试,在没有实时服务器的情况下,请指向您的 Spring 配置 声明 GraphQL HTTP 终端节点:
ApplicationContext context = ... ;
WebTestClient client =
WebTestClient.bindToApplicationContext(context)
.configureClient()
.baseUrl("/graphql")
.build();
HttpGraphQlTester tester = HttpGraphQlTester.create(client);
要在 Spring MVC 中进行测试,在没有实时服务器的情况下,请使用以下方法执行相同的操作:MockMvcWebTestClient
ApplicationContext context = ... ;
WebTestClient client =
MockMvcWebTestClient.bindToApplicationContext(context)
.configureClient()
.baseUrl("/graphql")
.build();
HttpGraphQlTester tester = HttpGraphQlTester.create(client);
或者,要针对在端口上运行的实时服务器进行测试:
WebTestClient client =
WebTestClient.bindToServer()
.baseUrl("http://localhost:8080/graphql")
.build();
HttpGraphQlTester tester = HttpGraphQlTester.create(client);
创建后,您可以开始使用相同的 API 执行请求,独立于底层
运输。如果您需要更改任何特定于传输的详细信息,请在
existing 创建具有自定义设置的新实例:HttpGraphQlTester
mutate()
HttpSocketGraphQlTester
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...
10.1.2. WebSocket 浏览器
WebSocketGraphQlTester
通过共享 WebSocket 连接执行 GraphQL 请求。
它是使用 Spring WebFlux 的 WebSocketClient 构建的,你可以按如下方式创建它:
String url = "http://localhost:8080/graphql";
WebSocketClient client = new ReactorNettyWebSocketClient();
WebSocketGraphQlTester tester = WebSocketGraphQlTester.builder(url, client).build();
WebSocketGraphQlTester
面向连接且多路复用。每个实例建立
它自己的单个共享连接,用于所有请求。通常,您需要使用单个
每个服务器仅实例。
创建后,您可以开始使用相同的 API 执行请求,独立于底层
运输。如果您需要更改任何特定于传输的详细信息,请在
existing 创建具有自定义设置的新实例:WebSocketGraphQlTester
mutate()
WebSocketGraphQlTester
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()
10.1.3. RSocket
RSocketGraphQlTester
使用 spring-messaging 执行 GraphQL
通过 RSocket 的请求:RSocketRequester
URI uri = URI.create("wss://localhost:8080/rsocket");
WebsocketClientTransport transport = WebsocketClientTransport.create(url);
RSocketGraphQlTester client = RSocketGraphQlTester.builder()
.clientTransport(transport)
.build();
RSocketGraphQlTester
面向连接且多路复用。每个实例建立
它自己的单个共享会话,用于所有请求。通常,您需要使用单个
每个服务器仅实例。您可以使用测试器上的方法来关闭
session 显式地进行。stop()
创建后,您可以开始使用相同的 API 执行请求,独立于底层
运输。RSocketGraphQlTester
10.1.4.GraphQlService
很多时候,在服务器端测试 GraphQL 请求就足够了,而无需使用
客户端通过传输协议发送请求。要直接针对 a 进行测试,请使用扩展:ExecutionGraphQlService
ExecutionGraphQlServiceTester
GraphQlService service = ... ;
ExecutionGraphQlServiceTester tester = ExecutionGraphQlServiceTester.create(service);
创建后,您可以开始使用相同的 API 执行请求,独立于底层
运输。ExecutionGraphQlServiceTester
ExecutionGraphQlServiceTester.Builder
提供用于自定义详细信息的选项:ExecutionInput
GraphQlService service = ... ;
ExecutionGraphQlServiceTester tester = ExecutionGraphQlServiceTester.builder(service)
.configureExecutionInput((executionInput, builder) -> builder.executionId(id).build())
.build();
10.1.5.WebGraphQlHandler
GraphQlService
扩展允许您在服务器端进行测试,而无需
一个客户。但是,在某些情况下,涉及服务器端传输是有用的
处理。
该扩展允许您在将请求移交给 for 之前通过链处理请求
请求执行:WebGraphQlTester
WebGraphQlInterceptor
ExecutionGraphQlService
WebGraphQlHandler handler = ... ;
WebGraphQlTester tester = WebGraphQlTester.create(handler);
此扩展的生成器允许您定义 HTTP 请求详细信息:
WebGraphQlHandler handler = ... ;
WebGraphQlTester tester = WebGraphQlTester.builder(handler)
.headers(headers -> headers.setBasicAuth("joe", "..."))
.build();
创建后,您可以开始使用相同的 API 执行请求,独立于底层
运输。WebGraphQlServiceTester
10.2. 请求
拥有 后,您可以开始测试请求。下面执行一个
查询项目并使用 JsonPath 提取
项目发布版本:GraphQlTester
String document = "{" +
" project(slug:\"spring-framework\") {" +
" releases {" +
" version" +
" }"+
" }" +
"}";
graphQlTester.document(document)
.execute()
.path("project.releases[*].version")
.entityList(String.class)
.hasSizeGreaterThan(1);
JsonPath 是相对于响应的 “data” 部分的。
您还可以在类路径中创建带有扩展名或 under 的文档文件,并通过文件名引用它们。.graphql
.gql
"graphql-test/"
例如,给定一个名为 in 的文件,其中包含内容:projectReleases.graphql
src/main/resources/graphql-test
query projectReleases($slug: ID!) {
project(slug: $slug) {
releases {
version
}
}
}
然后,您可以使用:
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 查询文件。 |
如果请求没有任何响应数据,例如 mutation,请使用 instead to 验证响应中没有错误:executeAndVerify
execute
graphQlTester.query(query).executeAndVerify();
有关错误处理的更多详细信息,请参阅 错误 。
10.3. 订阅
要测试订阅,请 call 而不是 to get a stream
的响应,然后从 Project Reactor 中使用它来检查流:executeSubscription
execute
StepVerifier
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();
只有 WebSocketGraphQlTester 或服务器端 GraphQlService
和 WebGraphQlHandler
扩展才支持订阅。
10.4. 错误
当您使用 时,响应中 “errors” 键下的任何错误都会导致
断言失败。要禁止显示特定错误,请在 之前使用 error 过滤器 :verify()
verify()
graphQlTester.query(query)
.execute()
.errors()
.filter(error -> ...)
.verify()
.path("project.releases[*].version")
.entityList(String.class)
.hasSizeGreaterThan(1);
您可以在生成器级别注册错误过滤器,以应用于所有测试:
WebGraphQlTester graphQlTester = WebGraphQlTester.builder(client)
.errorFilter(error -> ...)
.build();
如果要验证错误确实存在,并且与 相反,抛出一个
assertion 错误,如果没有,则改用:filter
exepect
graphQlTester.query(query)
.execute()
.errors()
.expect(error -> ...)
.verify()
.path("project.releases[*].version")
.entityList(String.class)
.hasSizeGreaterThan(1);
您还可以通过 检查所有错误,这样做还会将它们标记为
filtered,因此您还可以检查响应中的数据:Consumer
graphQlTester.query(query)
.execute()
.errors()
.satisfy(errors -> {
// ...
});