Jest — How To Mock a Function Call Inside a Module

Mocking function calls within a module

JEST logo
// f.jsexport function b(){
return 'b';
}
export function a(){
return b();
}

The Naive Approach

test('a', () => {
const f = require('./f');
jest.spyOn(f, 'b').mockReturnValue('c'); expect(f.a()).toBe('c');
// FAILED!
// expected 'c' got 'b'
})

Solution 1 — Splitting The Module Into Different Files

// b.jsexport function b(){
return 'b';
}
// f.jsimport {b} from './b';export function a(){
return b();
}
test('a', () => {
const b = require('./b');
const f = require('./f');
jest.spyOn(b, 'b').mockReturnValue('c'); expect(f.a()).toBe('c');
//PASSED!
})

Solution 2 — Calling The Mocked Function Using Exports

// f.jsexport function b(){
return 'b';
}
export function a(){
return exports.b();
}
test('a', () => {
const f = require('./f');
jest.spyOn(f, 'b').mockReturnValue('c'); expect(f.a()).toBe('c');
//PASSED!
})

A Sub-Optimal Solution Worth Mentioning — Exporting a Namespace Object

// f.jsconst f = {
b(){
return 'b';
},
a(){
return f.b();
}
};
export default f;
test('a', () => {
const f = require('./f');
jest.spyOn(f, 'b').mockReturnValue('c'); expect(f.a()).toBe('c');
//PASSED!
})
// won't work:
// import {a} from './f';
import f from './f';...f.a();

Another Sub-Optimal Solution— Using a Re-Wire Library

// f.jsexport function b(){
return 'b';
}
export function a(){
return b();
}
import {a, __set__} from './f';test('a', () => {
const f = require('./f');
// This rewires b to return 'c'
__set__(
'b', () => 'c');
expect(f.a()).toBe('c');
// PASSED!
})

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store