I have a controller that uses NestJS built-in Logger via dependency injection in constructor of the controller:
constructor(private readonly logger: Logger)
I want to be able to mock it in my Jest tests to see which methods and with what arguments are being called during logging. I tried this syntax:
providers[{
provide: Logger,
useValue: {
log: jest.fn(),
}
}]
In that case this line:
expect(Logger).toHaveBeenCalledTimes(1);
Returns: Matcher error: received value must be a mock or spy function
Any help will be highly appreciated!
In your test, you should get the logger back out of the DI context using moduleFixture.get(Logger)
(or something very similar) and then check expect(logger.log).toHaveBeenCalledTimes(1)
. Logger
itself is a class, not a spy or mock, so Jest doesn't know what to do with that.
Full solution that worked:
import { Test } from '@nestjs/testing';
let logger: Logger;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
providers: [
{
provide: Logger,
useValue: {
log: jest.fn(),
},
},
],
}).compile();
logger = moduleRef.get<Logger>(Logger);
});
And then later in the test itself:
expect(logger.log).toHaveBeenCalledTimes(1);
expect(logger.log).toHaveBeenCalledWith('Your log message here')