Jest: How to undo a global mock for certain tests in a file

Tags: ,



I want to mock Math.random for certain tests and use its original implementation for other tests. How can I achieve this? I’ve read about using jest.doMock and jest.dontMock, but I’ve bumped into a number of issues using them, like:

  • I seem to need require in order to use doMock and dontMock, but my project only uses ES6 modules for importing modules
  • Those functions also have issues taking in a global module like Math. I get an error when trying to use jest.doMock("Math.random"), which results in Cannot find module 'Math' from 'app.test.js'

I don’t necessarily need to use doMock and dontMock for my tests. They just seemed to be the closest thing I could find in the jest documentation to what I want to achieve. But I’m open to alternative solutions.

My function I want to test inside app.js…

export function getRandomId(max) {
    if (!Number.isInteger(max) || max <= 0) {
        throw new TypeError("Max is an invalid type");
    }
    return Math.floor(Math.random() * totalNumPeople) + 1;
}

Inside app.test.js…

describe("getRandomId", () => {
  const max = 10;
  Math.random = jest.fn();

  test("Minimum value for an ID is 1", () => {
      Math.mockImplementationOnce(() => 0);
      const id = app.getRandomId(max);
      expect(id).toBeGreaterThanOrEqual(1);
  });

  test("Error thrown for invalid argument", () => {
      // I want to use the original implementation of Math.random here
      expect(() => getRandomId("invalid")).toThrow();
  })
});

Answer

Try this:

describe("getRandomId", () => {
  const max = 10;
  let randomMock;

  beforeEach(() => {
    randomMock = jest.spyOn(global.Math, 'random');
  });

  test("Minimum value for an ID is 1", () => {
      randomMock.mockReturnValue(0);
      const id = getRandomId(max);
      expect(id).toBeGreaterThanOrEqual(1);
  });

  test("Error thrown for invalid argument", () => {
      // I want to use the original implementation of Math.random here
      randomMock.mockRestore(); // restores the original (non-mocked) implementation
      expect(() => getRandomId("invalid")).toThrow();
  })
});


Source: stackoverflow