如何使用Jest在NestJS中对自定义装饰器进行单元测试?
为NestJS GraphQL的CurrentUser装饰器编写Jest测试
针对你编写的CurrentUser参数装饰器,以下是基于Jest和TypeScript的测试方案,核心思路是模拟装饰器依赖的ExecutionContext和GqlExecutionContext,验证它能正确从请求上下文提取currentUser。
测试文件实现
创建对应测试文件current-user.decorator.spec.ts,代码如下:
import { ExecutionContext } from '@nestjs/common'; import { GqlExecutionContext } from '@nestjs/graphql'; import { CurrentUser, AuthUser } from './current-user.decorator'; describe('CurrentUser Decorator', () => { // 测试正常提取用户数据的场景 it('returns the currentUser attached to the request', () => { // 定义测试用的用户数据 const testUser: AuthUser = { id: 'test-user-123' }; // 模拟GqlExecutionContext.create的返回值,构造包含currentUser的请求上下文 const mockGqlContext = { getContext: () => ({ req: { currentUser: testUser }, }), }; jest.spyOn(GqlExecutionContext, 'create').mockReturnValue(mockGqlContext as any); // 模拟空的ExecutionContext(仅用于传递给装饰器) const mockExecutionContext = {} as ExecutionContext; // 调用装饰器并断言结果 const result = CurrentUser(null, mockExecutionContext); expect(result).toEqual(testUser); // 验证GqlExecutionContext.create被正确调用 expect(GqlExecutionContext.create).toHaveBeenCalledWith(mockExecutionContext); }); // 测试请求中无currentUser的边界场景 it('returns undefined when currentUser does not exist', () => { // 模拟不含currentUser的请求上下文 const mockGqlContext = { getContext: () => ({ req: {} }), }; jest.spyOn(GqlExecutionContext, 'create').mockReturnValue(mockGqlContext as any); const mockExecutionContext = {} as ExecutionContext; const result = CurrentUser(null, mockExecutionContext); expect(result).toBeUndefined(); }); });
关键测试逻辑说明
- Mock核心依赖:通过
jest.spyOn拦截GqlExecutionContext.create方法,让它返回我们预设的上下文对象,以此控制装饰器获取到的请求数据。 - 类型处理:测试中使用
as any对mock对象做类型断言,避免TypeScript因mock对象不满足完整接口而报错,这在测试场景下是合理的。 - 覆盖边界场景:除了正常提取用户的用例,额外测试
currentUser不存在的情况,确保装饰器行为符合预期。
内容的提问来源于stack exchange,提问作者Christian Guimarães
相关产品推荐
相关产品推荐

