I need to make an unit test for a controller who use injection with NestJS.
I don't know how to mock and spy this service (MyEmitter). I need to declare it in test.controller.spec.ts inside beforeEach() but how ?
test.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);
});
});
});
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. 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);
});
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With