我已经开始使用NestJS,并且对模拟 guard 有疑问
用于单元测试。
我正在尝试测试具有Guard附加方法的基本HTTP controller

当我向后卫注入(inject)服务时,我的问题就开始了(我需要后卫的ConfigService)。

运行测试时,DI无法解析保护器

  ● AppController › root › should return "Hello World!"

    Nest can't resolve dependencies of the ForceFailGuard (?). Please make sure that the argument at index [0] is available in the _RootTestModule context.

我的部队未能通过后卫:

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { ConfigService } from './config.service';

@Injectable()
export class ForceFailGuard implements CanActivate {

  constructor(
    private configService: ConfigService,
  ) {}

  canActivate(context: ExecutionContext) {
    return !this.configService.get().shouldFail;
  }
}

规范文件:

import { CanActivate } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ForceFailGuard } from './force-fail.guard';

describe('AppController', () => {
  let appController: AppController;

  beforeEach(async () => {

    const mock_ForceFailGuard = { CanActivate: jest.fn(() => true) };

    const app: TestingModule = await Test
      .createTestingModule({
        controllers: [AppController],
        providers: [
          AppService,
          ForceFailGuard,
        ],
      })
      .overrideProvider(ForceFailGuard).useValue(mock_ForceFailGuard)
      .overrideGuard(ForceFailGuard).useValue(mock_ForceFailGuard)
      .compile();

    appController = app.get<AppController>(AppController);
  });

  describe('root', () => {

    it('should return "Hello World!"', () => {
      expect(appController.getHello()).toBe('Hello World!');
    });

  });
});

我找不到有关此问题的示例或文档。我是否缺少某些东西,或者这是一个真正的问题?

感谢您的帮助,
谢谢。

最佳答案

提供的示例存储库存在3个问题:

  • 使用.overrideGuard()的Nestjs v6.1.1中存在一个错误-请参见https://github.com/nestjs/nest/issues/2070

    我已经确认其已在6.5.0中修复。
  • ForceFailGuardproviders中,但是其依赖项(ConfigService)在创建的TestingModule中不可用。

    如果要模拟ForceFailGuard,只需将其从providers中删除,然后让.overrideGuard()进行即可。
  • mock_ForceFailGuard拥有CanActivate而不是canActivate作为属性。

  • 工作示例(nestjs v6.5.0):

    import { CanActivate } from '@nestjs/common';
    import { Test, TestingModule } from '@nestjs/testing';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { ForceFailGuard } from './force-fail.guard';
    
    describe('AppController', () => {
      let appController: AppController;
    
      beforeEach(async () => {
        const mock_ForceFailGuard: CanActivate = { canActivate: jest.fn(() => true) };
    
        const app: TestingModule = await Test
          .createTestingModule({
            controllers: [AppController],
            providers: [
              AppService,
            ],
          })
          .overrideGuard(ForceFailGuard).useValue(mock_ForceFailGuard)
          .compile();
    
        appController = app.get<AppController>(AppController);
      });
    
      describe('root', () => {
        it('should return "Hello World!"', () => {
          expect(appController.getHello()).toBe('Hello World!');
        });
      });
    });
    

    关于unit-testing - Nestjs单元测试-模拟方法防护,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55848238/

    10-10 14:10