How to mock NestJS built-in Logger in Jest

Viewed 2903

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!

1 Answers

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')
Related