简体   繁体   English

单元测试 NestJS controller 与注入

[英]Unit testing NestJS controller with injection

I need to make an unit test for a controller who use injection with NestJS.我需要对使用 NestJS 注入的 controller 进行单元测试。

I don't know how to mock and spy this service (MyEmitter).我不知道如何模拟和监视此服务(MyEmitter)。 I need to declare it in test.controller.spec.ts inside beforeEach() but how?我需要在 beforeEach() 内的 test.controller.spec.ts 中声明它,但是如何?

test.controller.ts测试.controller.ts

import {
  Controller,
  Body,
  Post,
} from '@nestjs/common';
import {
  WebhookDto,
} from './dto/webhook.dto';
import { MyEmitter } from './test.events';
import { InjectEventEmitter } from 'nest-emitter';

@Controller()
export class TestController {
  constructor(
    @InjectEventEmitter() private readonly myEmitter: MyEmitter,
  ) {}

  @Post('webhook')
  public async postWebhook(
    @Body() webhookDto: WebhookDto,
  ): Promise<void> {
    ...
    this.myEmitter.emit('webhook', webhookDto);
  }
}

test.controller.spec.ts test.controller.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { TestController } from './test.controller';
import EventEmitter = require('events');
import { EVENT_EMITTER_TOKEN } from 'nest-emitter';
import { MyEmitter } from './test.events';

describe('Test Controller', () => {
  let testController: TestController;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [],
      providers: [
        {
          provide: EVENT_EMITTER_TOKEN,
          useValue: {
            emit: jest.fn(),
          },
        },
      ],
      controllers: [TestController],
    }).compile();

    testController = module.get<TestController>(TetsController);
  });

  describe('postWebhook', () => {
    it('should send the event', async () => {
      const myEmitterSpy = jest.spyOn(myEmitter, 'emit');
      const result = await testController.postWebhook({...});
      expect(myEmitterSpy).toBeCalledTimes(1);
    });
  });
});

Thank you really much for your help.非常感谢您的帮助。

The easiest way to go about it, with the setup you currently have is to use module.get() like you already are for the controller and pass in the EVENT_EMITTER_TOKEN constant, then save that to a value declared in the describe block, just like how the let testController: TestController works. go 关于它的最简单方法,您当前拥有的设置是使用module.get()就像您已经用于 controller 并传入EVENT_EMITTER_TOKEN常量,然后将其保存到describe块中声明的值,就像let testController: TestController是如何工作的。 Something like this should suffice:像这样的东西就足够了:

import { Test, TestingModule } from '@nestjs/testing';
import { TestController } from './test.controller';
import EventEmitter = require('events');
import { EVENT_EMITTER_TOKEN } from 'nest-emitter';
import { MyEmitter } from './test.events';

describe('Test Controller', () => {
  let testController: TestController;
  let myEmitter: MyEmitter;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [],
      providers: [
        {
          provide: EVENT_EMITTER_TOKEN,
          useValue: {
            emit: jest.fn(),
          },
        },
      ],
      controllers: [TestController],
    }).compile();

    testController = module.get<TestController>(TetsController);
    myEmitter = module.get<MyEmitter>(EVENT_EMITTER_TOKEN);
  });

  describe('postWebhook', () => {
    it('should send the event', async () => {
      const myEmitterSpy = jest.spyOn(myEmitter, 'emit'); // you can also add on mockResponse type functions here like mockReturnValue and mockResolvedValue
      const result = await testController.postWebhook({...});
      expect(myEmitterSpy).toBeCalledTimes(1);
    });
  });
});

Rather than injecting every dependencies (which should be tested separately), it is better to use jest.spyOn because controller has a service dependency or dependencies which might have other dependencies.与其注入每个依赖项(应单独测试),不如使用 jest.spyOn 更好,因为 controller 具有服务依赖项或可能具有其他依赖项的依赖项。

We should mock the method that will be called in the current test.我们应该模拟将在当前测试中调用的方法。

Here is the sample controller test.这是样品 controller 测试。

import { SampleController } from './sample.controller';
import { SampleService } from './sample.service';

describe('SampleController', () => {
  let sampleController: SampleController;
  let sampleService: SampleService;

  beforeEach(() => {
    // SampleService depends on a repository class
    // Passing null becasue SampleService will be mocked
    // So it does not need any dependencies.
    sampleService = new SampleService(null);
    // SampleController has one dependency SampleService
    sampleController = new SampleController(sampleService);
  });

  it('should be defined', async () => {
    expect(sampleController).toBeDefined();
  });

  describe('findAll', () => {
    it('should return array of samples', async () => {
      // Response of findAllByQuery Method
      // findAllByQUeryParams is a method of SampleService class.
      // I want the method to return an array containing 'test' value'.
      const expectedResult = ['test'];

      // Creating the mock method
      // The method structure is the same as the actual method structure.
      const findAllByQueryParamsMock = async (query: any) => expectedResult;

      // I am telling jest to spy on the findAllByQueryParams method
      // and run the mock method when the findAllByQueryParams method is called in the controller.
      jest
        .spyOn(sampleService, 'findAllByQueryParams')
        .mockImplementation(findAllByQueryParamsMock);

      const actualResult = await sampleController.findAll({});

      expect(actualResult).toBe(expectedResult);
    });
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Nestjs - 对从 CrudController 继承的 controller 进行单元测试 - Nestjs - Unit testing for a controller that is inherited from CrudController Controller 的 NestJS 单元测试:Mocking 从服务中删除不起作用 - NestJS Unit Testing for Controller: Mocking the Delete from Service Not Working NestJS - Mongoose @InjectConnection单元测试 - NestJS - Mongoose @InjectConnection unit testing nestjs 单元测试 createTestingModule 依赖注入 - nestjs unit test createTestingModule Dependency Injection 带有依赖注入的Typescript中的单元测试 - Unit testing in Typescript with Dependency Injection 使用 NestJS 服务单元测试未找到连接“默认” - Connection "default" was not found with NestJS Unit Testing of Service Controller 使用不同的守卫与 nestJS 进行集成测试 - Controller integration testing with nestJS using different guards Twilio API mocking 在 Nestjs 中使用 Jest 进行单元测试 - Twilio API mocking unit testing in Nestjs using Jest 我如何对 NestJS 中的 controller 应用防护装置进行单元测试? - How can I unit test that a guard is applied on a controller in NestJS? Typescript 中的单元测试,使用 Inversify 和 mocha 和 chai 进行依赖注入 - Unit testing in Typescript with Dependency Injection using Inversify with mocha and chai
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM