【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的讨论,所以我们应更仔细地阅读文档。

广告
将在 10 秒后关闭
bannerAds