Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to revert mocked function to original value in jest?

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?

like image 465
moslem Avatar asked Mar 10 '18 13:03

moslem


2 Answers

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();
like image 186
VivekN Avatar answered Oct 06 '22 10:10

VivekN


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: '[email protected] });

      // 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;

like image 41
JJ McGregor Avatar answered Oct 06 '22 11:10

JJ McGregor