如何用Jest测试NestJS中@Query()装饰器以实现100%覆盖率?
解决NestJS Resolver中@Query装饰器的测试覆盖率问题
要覆盖@Query()装饰器所在行的测试覆盖率,核心是让Nest的元数据系统真正执行装饰器内的逻辑,而非仅单独实例化Resolver类。以下是具体实现步骤:
1. 使用Nest测试模块完整加载Resolver
通过Test.createTestingModule初始化包含GraphQL模块的测试容器,让Nest自动解析并执行Resolver上的装饰器逻辑,这是最可靠的方式:
import { Test } from '@nestjs/testing'; import { MyResolver } from './my.resolver'; import { GraphQLModule } from '@nestjs/graphql'; import { Person } from './person.entity'; // 引入你的实体类 describe('MyResolver', () => { let resolver: MyResolver; beforeEach(async () => { const moduleRef = await Test.createTestingModule({ imports: [ GraphQLModule.forRoot({ autoSchemaFile: true, // 自动生成Schema触发装饰器解析 }), ], providers: [MyResolver], }).compile(); resolver = moduleRef.get<MyResolver>(MyResolver); }); // 基础测试:确保Resolver被正确初始化(触发装饰器执行) it('should be defined', () => { expect(resolver).toBeDefined(); }); // 业务逻辑测试:覆盖getPerson方法的同时,确保装饰器逻辑被统计 it('should return logged-in person', async () => { // 模拟装饰器注入的参数 const mockToken = 'valid-token-123'; const mockContext = {}; const mockProfiles = ['user', 'admin']; const result = await resolver.getPerson(mockToken, mockContext, mockProfiles); expect(result).toBeInstanceOf(Person); // 可根据业务逻辑添加更多断言 }); });
2. 排查覆盖率配置问题
如果按上述方法仍未覆盖装饰器行,检查你的jest.config.js配置,确保没有排除Resolver文件:
module.exports = { // 其他配置... collectCoverageFrom: [ 'src/**/*.ts', '!src/**/*.module.ts', // 排除模块文件(可选) '!src/main.ts', // 排除入口文件(可选) ], coveragePathIgnorePatterns: [ // 不要将你的Resolver文件加入忽略列表 ], };
关键原理说明
@Query()和@Resolver()装饰器本质是在类/方法定义时向Nest注册元数据,但Jest默认不会将模块加载阶段的装饰器执行逻辑纳入测试覆盖率,除非通过测试模块编译触发完整的元数据解析流程。单独实例化new MyResolver()只会执行类构造逻辑,不会触发装饰器内的Nest元数据注册逻辑,因此无法覆盖装饰器行。
内容的提问来源于stack exchange,提问作者Uder Moreira
相关产品推荐
相关产品推荐

