9. 测试
Spring for GraphQL 提供专门支持通过 HTTP 测试 GraphQL 请求, WebSocket 和 RSocket,以及直接对服务器进行测试。
要利用这个,可以添加spring-graphql-test(春-graphql-test)给你的构建:
dependencies {
// ...
testImplementation 'org.springframework.graphql:spring-graphql-test:1.0.6'
}
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<version>1.0.6</version>
<scope>test</scope>
</dependency>
</dependencies>
9.1.GraphQLTester
GraphQLTester是一个声明通用工作流用于测试 GraphQL 的契约
请求与底层传输无关。这意味着请求会被测试
无论底层传输是什么,API和任何传输内容都相同
具体配置是在构建时进行的。
要创建一个GraphQLTester通过客户端执行请求时,你需要以下扩展之一:
要创建一个GraphQLTester它在服务器端进行测试,无需客户端:
每个定义架构工人并附有与传输方式相关的选项。所有构建者都从从一个通用的基础 GraphQlTester 扩展架构工人跟 所有延期相关的选项。
9.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);
一次HttpGraphQLTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。 如果你需要更改任何运输具体细节,请使用变异()在一个 现存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...
9.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是面向连接且多路复用的。每个实例都为所有请求建立它自己的单一共享连接。通常,你会希望使用单个每个服务器的实例。
一次WebSocketGraphQlTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。 如果你需要更改任何运输具体细节,请使用变异()在一个 现存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的方法连接,例如在测试运行后。
9.1.3. Rocket
RSocketGraphQlTester使用RSocketRequester从Spring消息传递到执行GraphQL通过RSocket请求:
URI uri = URI.create("wss://localhost:8080/rsocket");
WebsocketClientTransport transport = WebsocketClientTransport.create(url);
RSocketGraphQlTester client = RSocketGraphQlTester.builder()
.clientTransport(transport)
.build();
RSocketGraphQlTester是面向连接且多路复用的。每个实例都为所有请求建立它自己的单一共享会话。通常,你会想用一个每个服务器只使用一个实例。你可以使用停止()在测试器上用来明确关闭会话。
一次RSocketGraphQlTester创建后,你可以开始使用相同的 API 执行请求,独立于底层
运输。
9.1.4.GraphQLService
很多时候,只需在服务器端测试 GraphQL 请求就足够了,无需使用客户端通过传输协议发送请求。直接对ExecutionGraphQLService,使用ExecutionGraphQlServiceTester外延:
GraphQlService service = ... ;
ExecutionGraphQlServiceTester tester = ExecutionGraphQlServiceTester.create(service);
一次ExecutionGraphQlServiceTester创建后,你可以开始使用相同的 API 执行请求,独立于底层
运输。
9.1.5.WebGraphQLHandler
这GraphQLService扩展允许你在服务器端测试,无需客户端。然而,在某些情况下,涉及服务器端传输是有用的处理与给定的模拟传输输入。
这WebGraphQLTester扩展允许你通过WebGraphQl拦截器在交接给ExecutionGraphQLService为 请求执行:
WebGraphQlHandler handler = ... ;
WebGraphQlTester tester = WebGraphQlTester.create(handler);
该扩展的构建器允许你定义HTTP请求细节:
WebGraphQlHandler handler = ... ;
WebGraphQlTester tester = WebGraphQlTester.builder(handler)
.headers(headers -> headers.setBasicAuth("joe", "..."))
.build();
一次WebGraphQlServiceTester创建后,你可以开始使用相同的 API 执行请求,独立于底层
运输。
9.2. 请求
一旦你有了GraphQLTester,你可以开始测试请求。以下作执行一个项目查询,并使用 JsonPath 从响应中提取项目发布版本:
String document = "{" +
" project(slug:\"spring-framework\") {" +
" releases {" +
" version" +
" }"+
" }" +
"}";
graphQlTester.document(document)
.execute()
.path("project.releases[*].version")
.entityList(String.class)
.hasSizeGreaterThan(1);
JsonPath 是相对于响应中的“data”部分的。
你也可以创建带有扩展名的文档文件.graphql或.gql下“graphql-test/”在类路径上,并用文件名来引用它们。
例如,给定一个名为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 | 设置鼻涕虫变量。 |
|
IntelliJ 的“JS GraphQL”插件支持带代码补全的 GraphQL 查询文件。 |
如果请求没有任何响应数据,例如变异,则使用执行与验证而不是执行为了验证回答中没有错误:
graphQlTester.query(query).executeAndVerify();
有关错误处理的更多细节,请参见错误部分。
9.3. 订阅
如需测试订阅,请致电执行订阅而不是执行获取一个响应流,然后使用步进验证器来自反应堆项目,检查该溪流:
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扩展。
9.4. 错误
当你使用verify(),响应中“error”键下的错误都会导致断言失败。要抑制特定错误,请在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();
如果你想验证错误的存在,并且与Filter抛出断言错误如果不正确,则使用典范相反:
graphQlTester.query(query)
.execute()
.errors()
.expect(error -> ...)
.verify()
.path("project.releases[*].version")
.entityList(String.class)
.hasSizeGreaterThan(1);
你也可以通过消费者,并且这样做也会标记为已过滤,因此你也可以在响应中检查数据:
graphQlTester.query(query)
.execute()
.errors()
.satisfy(errors -> {
// ...
});