Mocking ES and CommonJS modules with jest.mock()

Dominic Fraser
Aug 31, 2018 · 8 min read
Photo by NESA by Makers on Unsplash

Setup

npm install --save-dev jest
"scripts": {
"test": "jest --watchAll"
}
npm install --save-dev babel-preset-env
{
"presets": ["env"]
}

Mocking a Service

translationsService.js
const getTranslations = () => {
// makes network call to retrieve translations
// then parses result into an object of the below shape
const result = {
strings: {
'british-english': {
keyOne: 'string-one',
},
'malaysian': {
keyOne: 'string-satu'
},
},
};
return result;
};
module.exports = getTranslations;
testSubject.jsconst getTranslations = require('../helpers/translationsService');const moduleWeAreTesting = (language, bool = true) => {
const trans = getTranslations();
const getString = stringKey => {
return trans['strings'][language][stringKey];
};
const res = bool ? getString('agree') : getString('disagree'); return `They say: ${res}`
};
module.exports = moduleWeAreTesting;
const testSubject = require('./testSubject')jest.mock('../helpers/translationsService', () => () => ({  
strings: {
polish: {
agree: 'tak',
disagree: 'nie',
},
malaysian: {
agree: 'ya',
disagree: 'tidak',
},
},
}));
describe('testSubject tests', () => {
it('returns the correct string using default boolean', () => {
const moduleUnderTest = testSubject('malaysian');
expect(moduleUnderTest).toEqual('They say: ya');
});
it('returns the correct string on false', () => {
const moduleUnderTest = testSubject('polish', false);
expect(moduleUnderTest).toEqual('They say: nie');
});
});

Mocking a Class

myClass.jsclass MyClass {
constructor(name) {
this.name = name;
}
methodOne() {
return 1;
}
methodTwo() {
return 2;
}
}
export default MyClass;
import testSubject from './testSubject';jest.mock('./myClass', () => () => ({
name: 'Jody',
methodOne: () => 10,
methodTwo: () => 25,
}));

CommonJS Modules vs ES Modules

externalModule.jsconst ourCode = () => 'result';export default ourCode;
testSubject.jsimport ourCode from './externalModule';// use ourCode()
externalModule.jsconst ourCode = () => 'result';module.exports = ourCode;
testSubject.js
const ourCode = require('./externalModule');// use ourCode()
externalModule.jsconst ourCode = () => 'result';module.exports = ourCode;
testSubject.js
import ourCode from './externalModule';// use ourCode()
TypeError: ourCode is not a function
externalModule.jsconst ourCode = () => 'result';export default ourCode;
testSubject.js
const ourCode = require('./externalModule').default;// use ourCode()
Module keywords combinations
jest.mock('.\externalModule', () => () => 'mock result');
jest.mock('.\externalModule', () => ({
default: () => 'mock result',
}));

Quirks of mock functions inside mocks

const clickFn = jest.fn();const component = shallow(<MyComponent onClick={clickFn} />);// orfunction(arg1, arg2, clickFn);
import testSubject from './testSubject';const mockFunction = jest.fn();jest.mock('./myClass', () => () => ({
name: 'Jody',
methodOne: mockFunction,
}));
import testSubject from './testSubject';
import myHelper from ./myHelperFunctions;
jest.mock('./myHelperFunctions');describe('Tests', () => { beforeEach(() => {
myHelper.mockReset();
});
it('relies on the automock', () => {
functionThatCallsMyHelper();
expect(myHelper).toHaveBeenCalled();
});
it('is testing a specific implementation of the function', () => {
myHelper.mockReturnValueOnce('some value');
expect(functionThatCallsMyHelper()).toBe(false);
});
});

Final thoughts

Resources:

CodeClan

The latest posts from Scotland's first accredited digital skills academy

Dominic Fraser

Written by

Edinburgh, Scotland.

CodeClan

CodeClan

The latest posts from Scotland's first accredited digital skills academy