Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 697
oopinou Avatar asked Mar 16 '19 16:03

oopinou


People also ask

How do you mock an entire module in Jest?

You can just auto-mock the module using jest. mock : jest. mock('common/js/browser-utils');

How do you mock a function in a module Jest?

There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.

Can you mock an object in Jest?

When mocking global object methods in Jest, the optimal way to do so is using the jest. spyOn() method. It takes the object and name of the method you want to mock, and returns a mock function. The resulting mock function can then be chained to a mocked implementation or a mocked return value.

How do you mock a component in Jest?

To mock a React component, the most straightforward approach is to use the jest. mock function. You mock the file that exports the component and replace it with a custom implementation. Since a component is basically a function, the mock should also return a function.


1 Answers

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!
});
like image 84
Brian Adams Avatar answered Sep 29 '22 23:09

Brian Adams