You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Nestjs GraphQL项目中对各类GraphQL组件进行单元测试

NestJS GraphQL 各类组件单元测试方案

1. 自定义Scalar测试

自定义Scalar的核心逻辑都集中在serialize、parseValue、parseLiteral三个内置方法上,不需要启动完整Nest上下文,直接针对三个方法写单测即可:

  • 测试逻辑:
    • 给serialize传入业务侧要输出的JS值,校验返回的是否是符合GraphQL规范的输出值
    • 给parseValue传入客户端提交的变量值,校验解析后的JS值是否符合预期
    • 给parseLiteral传入手动构造的GraphQL AST节点,校验解析结果是否正确
  • 示例代码:
import { DateScalar } from './date.scalar';

describe('DateScalar', () => {
  const scalar = new DateScalar();

  it('serialize 应该把日期对象转为时间戳', () => {
    const date = new Date('2023-01-01');
    expect(scalar.serialize(date)).toBe(date.getTime());
  });

  it('parseValue 应该把时间戳转为日期对象', () => {
    const timestamp = 1672531200000;
    expect(scalar.parseValue(timestamp)).toEqual(new Date(timestamp));
  });
});

2. 自定义Directive测试

按照指令的作用分为两类,测试方式略有区别:

  • 模式指令(仅修改GraphQL Schema结构):手动构造测试用Schema,应用指令后校验生成的Schema结构是否符合预期即可
  • 运行时指令(会修改resolver执行逻辑):构造最小化的Nest GraphQL测试模块,注册指令和一个简单的测试用Resolver,发起模拟GraphQL查询后校验返回结果是否符合指令逻辑
  • 示例代码:
import { Test } from '@nestjs/testing';
import { GraphQLModule } from '@nestjs/graphql';
import { UpperDirective } from './upper.directive';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { gql } from 'apollo-server-express';
import * as request from 'supertest';

describe('UpperDirective', () => {
  let app;

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [
        GraphQLModule.forRoot<ApolloDriverConfig>({
          driver: ApolloDriver,
          typeDefs: gql`
            directive @upper on FIELD_DEFINITION
            type Query {
              test: String @upper
            }
          `,
          resolvers: {
            Query: {
              test: () => 'hello world'
            }
          },
          buildSchemaOptions: {
            directives: [new UpperDirective()]
          }
        })
      ]
    }).compile();

    app = module.createNestApplication();
    await app.init();
  });

  it('应该把字段返回值转为大写', async () => {
    const res = await request(app.getHttpServer())
      .post('/graphql')
      .send({ query: `{ test }` });
    expect(res.body.data.test).toBe('HELLO WORLD');
  });
});

3. Plugins测试

GraphQL插件都是基于Apollo的插件生命周期实现的,直接mock对应生命周期的参数,调用插件的对应钩子方法校验行为即可:

  • 测试逻辑:针对你用到的钩子(比如requestDidStart、willSendResponse等),构造mock的请求上下文、响应对象等参数,传入插件的钩子方法,校验插件的逻辑是否正确执行,比如是否打印了日志、是否修改了响应头等
  • 示例代码:
import { LoggingPlugin } from './logging.plugin';

describe('LoggingPlugin', () => {
  const plugin = new LoggingPlugin();
  const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();

  it('请求结束后应该打印查询日志', async () => {
    const mockContext = {
      request: { query: '{ test }' },
      response: { status: 200 }
    };
    const hook = plugin.requestDidStart(mockContext as any);
    await hook.willSendResponse(mockContext as any);
    expect(consoleLogSpy).toHaveBeenCalledWith('GraphQL query: { test }');
  });
});

4. 异常过滤器(含自定义异常)测试

自定义异常测试

直接实例化异常,校验异常的状态码、错误信息、扩展字段是否符合预期即可。

异常过滤器测试

异常过滤器的核心逻辑都在catch方法内,构造mock的异常对象和Host上下文参数,调用catch方法校验返回的响应内容是否符合预期:

  • 示例代码:
import { GqlExceptionFilter } from './gql-exception.filter';
import { BadRequestException } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

describe('GqlExceptionFilter', () => {
  const filter = new GqlExceptionFilter();
  const mockJson = jest.fn();
  const mockStatus = jest.fn(() => ({ json: mockJson }));

  beforeAll(() => {
    jest.spyOn(GqlExecutionContext, 'create').mockReturnValue({
      getContext: () => ({
        res: { status: mockStatus }
      })
    } as any);
  });

  it('应该把BadRequestException转为指定格式的GraphQL错误', () => {
    const exception = new BadRequestException('参数错误');
    filter.catch(exception, {} as any);
    expect(mockStatus).toHaveBeenCalledWith(400);
    expect(mockJson).toHaveBeenCalledWith(expect.objectContaining({
      errors: expect.arrayContaining([
        expect.objectContaining({ message: '参数错误' })
      ])
    }));
  });
});

内容的提问来源于stack exchange,提问作者Hantsy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:39:02