13

I mock a static function of a class in a test but i will effect on other test. because of nature of static function, the code is:

  test('A', async () => {
    expect.assertions(2);
    let mockRemoveInstance = jest.fn(() => true);
    let mockGetInstance = jest.fn(() => true);
    User.removeInstance = mockRemoveInstance;
    User.getInstance = mockGetInstance;
    await User.getNewInstance();
    expect(mockRemoveInstance).toHaveBeenCalled();
    expect(mockGetInstance).toHaveBeenCalled();
  });

  test('B', () => {
    let mockRemoveInstance = jest.fn();
    const Singletonizer = require('../utilities/Singletonizer');
    Singletonizer.removeInstance = mockRemoveInstance;
    User.removeInstance();
    expect.hasAssertions();
    expect(mockRemoveInstance).toHaveBeenCalled();
  });

In B test User.removeInstance() still is mocked by A test, how could reset the removeInstance() in to the original function that is defined by its class?

xavier
  • 1,860
  • 4
  • 18
  • 46
Kourosh
  • 917
  • 1
  • 11
  • 24

3 Answers3

20

You can try using jest.spyOn

Something like this should restore the function for you:-

    let mockRemoveInstance = jest.spyOn(User,"removeInstance");
    mockRemoveInstance.mockImplementation(() => true);

    User.removeInstance();
    expect(mockRemoveInstance).toHaveBeenCalledTimes(1);

    // After this restore removeInstance to it's original function

    mockRemoveInstance.mockRestore();
VivekN
  • 1,562
  • 11
  • 14
  • This works perfectly for me! This came in useful when I tried `jest.fn` for mocking some DOM functions from the document object and I couldn't remove the mock for the rest of my tests – Qarun Qadir Bissoondial Jul 23 '21 at 19:12
3

I had a similar issue where I had to mock an external function for one test, but Jest wouldn't / couldn't restore the ORIGINAL value of the function.

So I ended up using this, but I would love to know if there's a better way

   it('should restore the mocked function', async () => {
      const copyOfFunctionToBeMocked = someClass.functionToBeMocked;
      someClass.functionToBeMocked = jest.fn().mockReturnValueOnce(false);

      // someClass.functionToBeMocked gets called in the following request
      const res = await supertest(app)
        .post('/auth/register')
        .send({ email: 'abc@def.com });

      // Not ideal but mockReset and mockRestore only reset the mocked function, NOT to its original state
      someClass.functionToBeMocked = copyOfFunctionToBeMocked;

      expect(...).toBe(...);
    });

Inelegant but it works;

JJ McGregor
  • 182
  • 1
  • 12
0

In Vue JS, I did the following

// mock **myFunctionName**
 wrapper.vm.myFunctionName = jest.fn()

 wrapper.vm.somOtherFunction()

 expect(wrapper.vm.myFunctionName).toHaveBeenCalled()

// Remove mock from **myFunctionName**
 wrapper.vm.myFunctionName.mockRestore()
Taimoor Changaiz
  • 10,250
  • 4
  • 49
  • 53