Patrick Finnigan
Patrick Finnigan

Reputation: 1947

How do I clear jest state (spies, mocks) between each test?

I'm having an issue where jest is not clearing state between tests. I tried calling restoreAllMocks() in a beforeEach() and in an afterEach() and this didn't clear my jest.spyOn(x, 'y').mockImplementation() stub. I also tried clearAllMocks() and resetAllMocks(), no luck.

My spec module:

function mockFeatureFlag(flagToMock: Flag) {
  jest.spyOn(FeatureFlags, 'singleton').mockImplementation(
    () =>
      ({
        getFeatureFlag: (flag: Flag) =>
          new Promise(resolve => {
            if (flag === flagToMock) {
              resolve(true);
            } else {
              resolve(false);
            }
          }),
      } as any),
  );
}

  describe('bufferMinutesForDistance', () => {
    it('for small distances uses min buffer of 3h', async () => {
      const minutes = await util.bufferMinutesForDistance(1);
      expect(minutes).toBe(3 * 60);
    });

    it('for small distances when HALF_GHOST_BUFFER flag is true uses min buffer of 3h', async () => {
      mockFeatureFlag(Flag.HALF_GHOST_BUFFER);
      const minutes = await util.bufferMinutesForDistance(1);
      expect(minutes).toBe(3 * 60);
    });

    it('for long distances uses 12h buffer', async () => {
      const minutes = await util.bufferMinutesForDistance(1000);
      expect(minutes).toBe(12 * 60);
    });

    it('for long distances when HALF_GHOST_BUFFER flag is true cuts 12h buffer by half', async () => {
      mockFeatureFlag(Flag.HALF_GHOST_BUFFER);
      const minutes = await util.bufferMinutesForDistance(1000);
      expect(minutes).toBe(6 * 60);
    });
  });

There are 4 tests here. In tests 1 and 3, where I am not explicitly mocking the feature flag to return true, I expect it to return false (feature flags are false by default). Here, I call mockImplementation to make the feature flag return true in test 2. However, when running the tests, I see that the flag returns true in test 3 as well. I was not expecting this, since it means the spy state is leaking between tests.

How do I prevent jest from leaking state between tests?

Upvotes: 2

Views: 4440

Answers (1)

Patrick Finnigan
Patrick Finnigan

Reputation: 1947

This is an open issue (potential bug) in Jest: https://github.com/facebook/jest/issues/7083

By default, Jest does not clear spy state between tests. They can be individually, explicitly removed in/after the test that creates them, or you can change your jest config to automatically clear spy state between tests. The following properties can be set in your jest.config.js to tell Jest to clear state between tests:

  restoreMocks: true,
  clearMocks: true,
  resetMocks: true,

Upvotes: 3

Related Questions