0

I am writing some code, I have a dummy scenario of what I am trying to achieve show below. I have a function that I am testing, that uses functions from the a different module. I want to mock the functions for the imported module. How do I go about doing it?

I have seen this solution, but the jest.doMock function does not work in commonJS - is what I understand. This is for a node backend project.

Any help would be appreciated. Thanks

// helper.js

let add = (a, b) => a + b;
let mult = (a, b) => a * b;

module.exports = { add, sub, mult };
// index.js

const { add, mult } = require('./helper');

const add5thenMultiply2 = (a) => {
  const res1 = add(a, 5);
  return mult(res1, 2);
};

module.exports = { add5thenMultiply2 };
// index.test.js

const { add5thenMultiply2 } = require('./index');

describe('index', () => {
  it('returns right value', () => {
    const input = 3;
    const expected = 16;
    const result = add5thenMultiply2(input);
    expect(result).toEqual(expected);
  });

  it('works with mock', () => {
    // mock add() such that it always returns 100, but for this test only
    const input = 3;
    const expected = 200;
    const result = add5thenMultiply2(input);
    expect(result).toEqual(expected);
  });
});
Devatanu
  • 507
  • 5
  • 13

1 Answers1

1

jest.doMock(moduleName, factory, options) works fine with commonJS. You also need to use jest.requireActual(moduleName) to mock ./helper module partially which means only mock add function, keep using the original mult function.

E.g.

helper.js:

let add = (a, b) => a + b;
let mult = (a, b) => a * b;

module.exports = { add, mult };

index.js:

const { add, mult } = require('./helper');

const add5thenMultiply2 = (a) => {
  const res1 = add(a, 5);
  return mult(res1, 2);
};

module.exports = { add5thenMultiply2 };

index.test.js:

describe('index', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('returns right value', () => {
    const { add5thenMultiply2 } = require('./index');
    const input = 3;
    const expected = 16;
    const result = add5thenMultiply2(input);
    expect(result).toEqual(expected);
  });

  it('works with mock', () => {
    jest.doMock('./helper', () => {
      return {
        ...jest.requireActual('./helper'),
        add: jest.fn().mockReturnValue(100),
      };
    });
    const { add5thenMultiply2 } = require('./index');
    const input = 3;
    const expected = 200;
    const result = add5thenMultiply2(input);
    expect(result).toEqual(expected);
  });
});

test result:

 PASS  examples/67830139/index.test.js (7.751 s)
  index
    ✓ returns right value (6554 ms)
    ✓ works with mock (2 ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 helper.js |     100 |      100 |     100 |     100 |                   
 index.js  |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.308 s
Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • Yup, that worked thanks! It's a shame you have to `require` the function under test in every `it` block, but I can live with that. – Devatanu Jun 04 '21 at 08:46