Ghassan Karwchan
Ghassan Karwchan

Reputation: 3540

Jest mocking module

I am writing unit tests for a node application using Jest. The Node code is using a third party library to log information.

The library has a function getLogger which you should call to return a logger object.

I am trying to mock the calls for that library and detect its calls in my unit test. The node code is as follows:

const logger = require('third-party-libary').getLogger('myModule')
....
function submitSomething() {
   ....
   logger.info('log something')
}

In my Jest unit test, I tried to mock those logger calls in many different ways, with no success, and always come back as "logger is not defined"

I tried:

jest.mock('third-party-library');
const loggerFactory = require('third-party-library');
const logger = {
   error: jest.fn(),
   info: jest.fn()
};
loggerFactory.getLogger.mockImplementation(() => logger);

But it always return error :

cannot find "info" for null object

I tried this as well:

jest.mock('third-party-library')
const loggerFactory = require('third-party-library');
const logger = {
   error: jest.fn(),
   info: jest.fn()
};
loggerFactory.getLogger = () => logger

I tried this:

jest.mock('third-party-library')
    const loggerFactory = require('third-party-library');
    const logger = {
       error: jest.fn(),
       info: jest.fn()
    };
    loggerFactory.getLogger = jest.fn(() => logger)

With the same error I switched between the jest.mock to make it after the require, with no luck

Upvotes: 3

Views: 1958

Answers (1)

Brian Adams
Brian Adams

Reputation: 45810

Your approach works fine, just note that your code creates logger as soon as it runs so the mock for getLogger has to be in place before the code is required:

jest.mock('third-party-library');
const loggerFactory = require('third-party-library');
const logger = {
   error: jest.fn(),
   info: jest.fn()
};
// const { submitSomething } = require('./code');  <= would NOT work here
loggerFactory.getLogger.mockReturnValue(logger);
const { submitSomething } = require('./code');  // <= works here

test('submitSomething', () => {
  submitSomething();
  expect(logger.info).toHaveBeenCalledWith('log something');  // Success!
});

Upvotes: 2

Related Questions