Mock/Spy exported functions within a single module in Jest

A brief guide on how to test that a function depends on another function exported by the same module

Davide Rama
Nov 12, 2018 · 3 min read

The Problem

You have a module which exports multiple functions. One of these functions depends on another function of the same module.

export function foo () { ... }
export function bar () { foo() }
import * as myModule from './myModule';test('calls myModule.foo', () => {
  const fooSpy = jest.spyOn(myModule, 'foo');  myModule.bar();  expect(fooSpy).toHaveBeenCalledTimes(1);
});

Truth is, it is not about Jest. It is about JavaScript itself.

The Reason

In more detail, it is because of how Javascript is compiled by babel. This is the output of myModule once compiled:

var foo = function foo() {};
var bar = function bar() { foo(); };

exports.foo = foo;
exports.bar = bar;

The Solution(s)

While investigating on the internet you might find some solutions to overcome this “issue” adopting the usage of the require function.

A single source of truth

The first strategy you could use is storing the references of your methods in an object which you will then export. bar will invoke the reference of foo stored in that object.

var foo = function foo() {};
var bar = function bar() { exportFunctions.foo(); };const exportFunctions = {
  foo,
  bar
};export default exportFunctions;

Separation of concerns

On the other hand, you can separate the concerns of your code and declare the two functions in two different modules.

// fooModule.js
export function foo () { ... }// barModule.js
export function bar () { fooModule.foo() }
import foo from './fooModule';
import bar from './barModule';test('calls fooModule.foo', () => {
  const fooSpy = jest.spyOn(fooModule, 'foo');  bar();  expect(fooSpy).toHaveBeenCalledTimes(1);
});