How to create a noop logger instance of Pino logger?

589 Views Asked by At

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.

1

There are 1 best solutions below

1
Nazrul Chowdhury On BEST ANSWER

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(),
    ...
  })),
}))