【NestJS】当GraphQL初学者尝试编写测试时遇到了困难
結果
与常规的REST不同,GraphQL通常将http状态码返回为200,并把错误信息放在响应的errors键中,因此在测试请求是否成功时不应该通过res.status来判断。
简而言之
当使用NestJS(驱动器是ApolloDriver)和GraphQL实现认证后,如果按照以下方式编写解析器的测试,会报错说res.status为200。
import { Test, TestingModule } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import * as request from "supertest";
import { HogeModule } from "src/hoge.module";
describe("HogeResolver", () => {
let app: INestApplication;
let HogeService = { findUnique: () => ["test"], findMany: () => ["test2"] };
let resolver: HogeResolver;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [HogeModule],
})
.overrideProvider(HogeService)
.useValue(HogeService).compile();
resolver = module.get<HogeResolver>(HogeResolver);
app = module.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
});
it("should be defined", () => {
expect(resolver).toBeDefined();
});
it("sample", async () => {
const res = await request(app.getHttpServer())
.post("/graphql")
.send({
query: "{ hoge { edges { node { id } } } }",
})
expect(res.status).toBe(401)
});
});
console.log(res.text)可以查看res的内容。
{"errors":[{"message":"Unauthorized","extensions":{"code":"UNAUTHENTICATED","response":{"statusCode":401,"message":"Unauthorized"}}}],"data":null}
因为是这样的,看起来像是401错误,所以为什么res.status是200?????那种感觉。
→在进行了各种调查后,结论如所述,REST与GraphQL在返回错误方面存在差异。在GraphQL中,通常会以http状态码200返回,并将错误信息放入响应的errors键中。
所以最终结果是如下的。
import { Test, TestingModule } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import * as request from "supertest";
import { HogeModule } from "src/hoge.module";
describe("HogeResolver", () => {
let app: INestApplication;
let HogeService = { findUnique: () => ["test"], findMany: () => ["test2"] };
let resolver: HogeResolver;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [HogeModule],
})
.overrideProvider(HogeService)
.useValue(HogeService).compile();
resolver = module.get<HogeResolver>(HogeResolver);
app = module.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
});
it("should be defined", () => {
expect(resolver).toBeDefined();
});
it("sample", async () => {
const res = await request(app.getHttpServer())
.post("/graphql")
.send({
query: "{ hoge { edges { node { id } } } }",
})
expect(res.body.errors[0].extensions.response.statusCode).toBe(401);
});
});
备考
由于本次使用Prisma作为ORM,所以HogeService = { findUnique: () => [“test”], findMany: () => [“test2”] }这部分代码是这样的,但需要注意该部分会根据不同的ORM而改变。
这实际上是关于GraphQL规范而非NestJS的讨论,所以我们应更仔细地阅读文档。