matteo
matteo

Reputation: 1725

Jest: how to mock a function which is used by another function of the same module

I am trying to test a function which depends on another function in the same module. I would like to mock the second one and the approach that I have tried is the following:

utils.js:

const buildEngine = () => 'Engine';

const buildCar = () => {
  const engine = buildEngine();
  return engine + ' and ' + 'Car Body';
};

module.exports = {
  buildEngine,
  buildCar
};

utils.spec.js:

function mockModule() {
  const original = require.requireActual('./utils');
  return { ...original, buildEngine: jest.fn(() => 'Mock Engine') };
}

it('Builds a Car', () => {
  jest.mock('./utils', () => mockModule());

  const utils = require.requireMock('./utils');

  expect(utils.buildEngine()).toBe('Mock Engine');
  expect(utils.buildCar()).toBe('Mock Engine and Car Body');
});

What happens is that even if I am able to mock the "buildEngine" function, when I test the "buildCar" function this continues to reference the unmocked "buildEngine". Please help.

Upvotes: 2

Views: 1501

Answers (1)

Lin Du
Lin Du

Reputation: 102597

Here is the solution:

utils.js:

const buildEngine = () => 'Engine';

const buildCar = () => {
  const engine = exports.buildEngine();
  return engine + ' and ' + 'Car Body';
};

exports.buildEngine = buildEngine;
exports.buildCar = buildCar;

utils.spec.js:

const utils = require('./utils');

describe('utils', () => {
  it('Builds a Car', () => {
    const buildEngineSpy = jest.spyOn(utils, 'buildEngine').mockReturnValue('Mock Engine');
    expect(utils.buildCar()).toBe('Mock Engine and Car Body');
    expect(buildEngineSpy).toBeCalledTimes(1);
    buildEngineSpy.mockRestore();
  });

  it('build engine original implementation', () => {
    expect(utils.buildEngine()).toBe('Engine');
    expect(utils.buildCar()).toBe('Engine and Car Body');
  });
});

Unit test result:

 PASS  src/stackoverflow/46437290/utils.spec.js
  utils
    ✓ Builds a Car (4ms)
    ✓ build engine original implementation (1ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.908s, estimated 2s

Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/46437290

Upvotes: 3

Related Questions