Sapan Diwakar

Software developer

Follow me on Twitter Check out my code on GitHub View some of my designs on Dribbble Take a look at my Linked In profile

Mocking with Jest

Jest provides several different ways to mock out things. Here's an effort to list out the most useful ones in a short post.

Manual Mocks

The most basic kind of mocking is by providing a __mocks__ directory next to the module you want to mock and provide a mock implementation of that module. So if you want to mock app/core/request.ts, you will add a app/core/__mocks__/request.ts file with your custom mock implementation. To mock node_modules, you can put a __mocks__ folder in the root of your project.

To load these mocks, you need to call jest.mock('moduleName') in the test file:

import uuid from 'uuid';  
import { request } from '../request';

jest.mock('uuid');  
jest.mock('../request');  

To automatically mock such modules always, you can use automock: true when configuring jest. In that case, if you need to fallback to the default implementation, you need to manually unmock the module with jest.unmock('moduleName').

CommonJS module

You can also provide a custom implementation right in the test file. For example, for a commonjs module, all you need is:

jest.mock('./commonjs', jest.fn(() => true));  

ES modules

Automatic Mocks

If you just need to spy on method calls of an ES module, jest provides automatic mocks that you can use. For example, for an exported class called SoundManager, all you need is jest.mock('./sound-manager) and the class will be replaced by jest's automatic mock.

You can now do things like

const mockSoundManagerInstance = SoundManager.mock.instances[0];  
const mockPlaySoundFile = mockSoundManagerInstance.playSoundFile;  
expect(mockPlaySoundFile).toHaveBeenCalledTimes(1);  

Custom Mock

Same is possible for ES modules. You can mock them inline, but you need to set the __esModule flag on your mock implementation. You can mock both default exports and named exports.

jest.mock('./sound-manager', () => {  
  __esModule: true,
  default: CustomSoundManager,
  createSoundManager: jest.fn(() => new CustomSoundManager()) // Could be any named export
});