簡體   English   中英

單元測試 NestJS controller 與注入

[英]Unit testing NestJS controller with injection

我需要對使用 NestJS 注入的 controller 進行單元測試。

我不知道如何模擬和監視此服務(MyEmitter)。 我需要在 beforeEach() 內的 test.controller.spec.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

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);
    });
  });
});

非常感謝您的幫助。

go 關於它的最簡單方法,您當前擁有的設置是使用module.get()就像您已經用於 controller 並傳入EVENT_EMITTER_TOKEN常量,然后將其保存到describe塊中聲明的值,就像let testController: TestController是如何工作的。 像這樣的東西就足夠了:

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);
    });
  });
});

與其注入每個依賴項(應單獨測試),不如使用 jest.spyOn 更好,因為 controller 具有服務依賴項或可能具有其他依賴項的依賴項。

我們應該模擬將在當前測試中調用的方法。

這是樣品 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM