0

I want to test a function (using jest) which takes a pino.Logger type object as an argument. I have failed at trying to mock it, so all I need is a noop Logger instance that does nothing. I'm mainly a Go dev and I don't have any problem defining the noop Zap logger or custom logger that implements Zap logger interface.

I tried mocking it like this:

import Pino from 'pino';

jest.mock('pino');

const childFakeLogger = { warn: jest.fn() };
const fakeLogger = {
  child: jest.fn(() => childFakeLogger)
};

beforeAll(() => {
  Pino.mockImplementation(() => fakeLogger); // err msg="Property 'mockImplementation' does not exist on type 'typeof pino'." 
});

I've tried starting a noop definition like this:

import Pino, { Logger } from 'pino';

const noOp: Pino.LogFn = (..._args: any[]) => {};

export const noopLogger: Logger = {
  child: any, // don't know how to define this
  level: 'trace',
  fatal: noOp,
  error: noOp,
  warn: noOp,
  info: noOp,
  debug: noOp,
  trace: noOp,
};

Which gives the following error:

Type '{ level: string; fatal: Pino.LogFn; error: Pino.LogFn; warn: Pino.LogFn; info: Pino.LogFn; debug: Pino.LogFn; trace: Pino.LogFn; }' is not assignable to type 'Logger'.
Property 'silent' is missing in type '{ level: string; fatal: Pino.LogFn; error: Pino.LogFn; warn: Pino.LogFn; info: Pino.LogFn; debug: Pino.LogFn; trace: Pino.LogFn; }' but required in type 'BaseLogger'.

But I can't figure out how to fully define it according to the Pino.BaseLogger definition.

Benjamin R
  • 555
  • 6
  • 25

1 Answers1

1

you are trying to use mockImplementation directly on the Pino module, but it should be used on the mock returned by jest.mock('pino')

import Pino from 'pino'

jest.mock('pino', () => {
 const childFakeLogger = { warn: jest.fn() }
 const fakeLogger = {
   child: jest.fn(() => childFakeLogger),
   // Define other methods you need to use in the function being tested (info, error and so on..) as jest.fn().
   // For a noop Logger you can simply define them as jest.fn().
   info: jest.fn(),
   error: jest.fn(),
 }
 return jest.fn(() => fakeLogger);
})

/// Now you can import the function that uses the Pino.Logger type object and test it with the mocked Logger.

or may be even something like this,

jest.mock('pino', () => ({
  child: jest.fn(() => ({
    warn: jest.fn(),
    info: jest.fn(),
    error: jest.fn(),
    ...
  })),
}))
Nazrul Chowdhury
  • 1,483
  • 1
  • 5
  • 11
  • Thanks Nazrul, that's very helpful. I'll give this a go and mark this as answered if it does the job (looks like it does) – Benjamin R Jul 25 '23 at 16:27