9. 测试

Spring for GraphQL 提供专门支持通过 HTTP 测试 GraphQL 请求, WebSocket 和 RSocket,以及直接对服务器进行测试。spring-doc.cadn.net.cn

要利用这个,可以添加spring-graphql-test(春-graphql-test)给你的构建:spring-doc.cadn.net.cn

格拉德勒
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和任何传输内容都相同 具体配置是在构建时进行的。spring-doc.cadn.net.cn

要创建一个GraphQLTester通过客户端执行请求时,你需要以下扩展之一:spring-doc.cadn.net.cn

要创建一个GraphQLTester它在服务器端进行测试,无需客户端:spring-doc.cadn.net.cn

每个定义架构工人并附有与传输方式相关的选项。所有构建者都从从一个通用的基础 GraphQlTester 扩展架构工人跟 所有延期相关的选项。spring-doc.cadn.net.cn

9.1.1. HTTP

HttpGraphQLTester使用 WebTestClient 执行通过 HTTP 进行 GraphQL 请求,是否配备实时服务器,具体取决于具体方式WebTestClient已配置。spring-doc.cadn.net.cn

要在没有实时服务器的情况下测试 Spring WebFlux,请指向你的 Spring 配置该配置声明了 GraphQL HTTP 端点:spring-doc.cadn.net.cn

ApplicationContext context = ... ;

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

HttpGraphQlTester tester = HttpGraphQlTester.create(client);

在没有实时服务器的情况下,在 Spring MVC 中测试时,也可以用同样的方法进行测试MockMvcWebTestClient:spring-doc.cadn.net.cn

ApplicationContext context = ... ;

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

HttpGraphQlTester tester = HttpGraphQlTester.create(client);

或者用一个运行在端口上的实时服务器测试:spring-doc.cadn.net.cn

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

HttpGraphQlTester tester = HttpGraphQlTester.create(client);

一次HttpGraphQLTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。 如果你需要更改任何运输具体细节,请使用变异()在一个 现存HttpSocketGraphQLTester创建带有自定义设置的新实例:spring-doc.cadn.net.cn

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构建的,你可以按以下方式创建:spring-doc.cadn.net.cn

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

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

WebSocketGraphQlTester是面向连接且多路复用的。每个实例都为所有请求建立它自己的单一共享连接。通常,你会希望使用单个每个服务器的实例。spring-doc.cadn.net.cn

一次WebSocketGraphQlTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。 如果你需要更改任何运输具体细节,请使用变异()在一个 现存WebSocketGraphQlTester创建带有自定义设置的新实例:spring-doc.cadn.net.cn

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的方法连接,例如在测试运行后。spring-doc.cadn.net.cn

9.1.3. Rocket

RSocketGraphQlTester使用RSocketRequester从Spring消息传递到执行GraphQL通过RSocket请求:spring-doc.cadn.net.cn

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

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

RSocketGraphQlTester是面向连接且多路复用的。每个实例都为所有请求建立它自己的单一共享会话。通常,你会想用一个每个服务器只使用一个实例。你可以使用停止()在测试器上用来明确关闭会话。spring-doc.cadn.net.cn

一次RSocketGraphQlTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。spring-doc.cadn.net.cn

9.1.4.GraphQLService

很多时候,只需在服务器端测试 GraphQL 请求就足够了,无需使用客户端通过传输协议发送请求。直接对ExecutionGraphQLService,使用ExecutionGraphQlServiceTester外延:spring-doc.cadn.net.cn

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

一次ExecutionGraphQlServiceTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。spring-doc.cadn.net.cn

9.1.5.WebGraphQLHandler

GraphQLService扩展允许你在服务器端测试,无需客户端。然而,在某些情况下,涉及服务器端传输是有用的处理与给定的模拟传输输入。spring-doc.cadn.net.cn

WebGraphQLTester扩展允许你通过WebGraphQl拦截器在交接给ExecutionGraphQLService为 请求执行:spring-doc.cadn.net.cn

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

该扩展的构建器允许你定义HTTP请求细节:spring-doc.cadn.net.cn

WebGraphQlHandler handler = ... ;

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

一次WebGraphQlServiceTester创建后,你可以开始使用相同的 API 执行请求,独立于底层 运输。spring-doc.cadn.net.cn

9.1.6. 建造者

GraphQLTester定义了父母架构工人提供通用配置选项所有扩展的构建者。它允许你配置以下内容:spring-doc.cadn.net.cn

9.2. 请求

一旦你有了GraphQLTester,你可以开始测试请求。以下作执行一个项目查询,并使用 JsonPath 从响应中提取项目发布版本:spring-doc.cadn.net.cn

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

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

JsonPath 是相对于响应中的“data”部分的。spring-doc.cadn.net.cn

你也可以创建带有扩展名的文档文件.graphql.gql“graphql-test/”在类路径上,并用文件名来引用它们。spring-doc.cadn.net.cn

例如,给定一个名为projectReleases.graphqlsrc/main/resources/graphql-test,内容如下:spring-doc.cadn.net.cn

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

然后你可以使用:spring-doc.cadn.net.cn

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 查询文件。spring-doc.cadn.net.cn

如果请求没有任何响应数据,例如变异,则使用执行与验证而不是执行为了验证回答中没有错误:spring-doc.cadn.net.cn

graphQlTester.query(query).executeAndVerify();

有关错误处理的更多细节,请参见错误部分spring-doc.cadn.net.cn

9.3. 订阅

如需测试订阅,请致电执行订阅而不是执行获取一个响应流,然后使用步进验证器来自反应堆项目,检查该溪流:spring-doc.cadn.net.cn

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或服务器端的支持GraphQLServiceWebGraphQLHandler扩展。spring-doc.cadn.net.cn

9.4. 错误

当你使用verify(),响应中“error”键下的错误都会导致断言失败。要抑制特定错误,请在verify():spring-doc.cadn.net.cn

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

你可以在构建者层面注册错误过滤器,应用到所有测试:spring-doc.cadn.net.cn

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

如果你想验证错误的存在,并且与Filter抛出断言错误如果不正确,则使用典范相反:spring-doc.cadn.net.cn

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

你也可以通过消费者,并且这样做也会标记为已过滤,因此你也可以在响应中检查数据:spring-doc.cadn.net.cn

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