oopinou
oopinou

Reputation: 153

Mock an entire module with Jest in Javascript

I searched for a very long time how to mock any module with jest (like rewire does). I finally manage to do it this way, and it work like a charm :

jest.mock('common/js/browser-utils', () => ({
    openBrowser: jest.fn()
}));
const { openBrowser: openBrowserSpy } = jest.requireMock(
    'common/js/browser-utils'
);

But i wonder if there is another fast way to do so ? I saw the genMockFromModule method but i never makes it work (maybe it's not for that usage.)

What i want is simple : mocking a module by a jest.fn() (or any auto mechanism), then being able to access this jest.fn() in my tests (here: openBrowserSpy) to expect(assertions) on it

Upvotes: 10

Views: 20570

Answers (1)

Brian Adams
Brian Adams

Reputation: 45780

You can just auto-mock the module using jest.mock:

jest.mock('common/js/browser-utils');

The docs could probably be improved with a better description of what "auto-mocked version" means, but what happens is that Jest keeps the API surface of the module the same while replacing the implementation with empty mock functions.

Complete example

browser-utils.js

export const openBrowser = () => { /* do something */ };

code.js

import { openBrowser } from './browser-utils';

export const func = () => {
  /* do stuff */
  openBrowser();
  /* do other stuff */
}

code.test.js

jest.mock('./browser-utils');  // create an auto-mock of the module

import { openBrowser } from './browser-utils';  // openBrowser is already an empty mock function
import { func } from './code';

test('func', () => {
  func();
  expect(openBrowser).toHaveBeenCalled();  // Success!
});

Bonus: Mock single function

To mock a single function you can use jest.spyOn like this:

import * as browserUtils from './browser-utils';
import { func } from './code';

test('func', () => {
  const spy = jest.spyOn(browserUtils, 'openBrowser');
  spy.mockImplementation();  // replace implementation with empty mock function (optional)
  func();
  expect(spy).toHaveBeenCalled();  // Success!
});

Upvotes: 16

Related Questions