Unable to clear `setInterval` from Jest fake timer

Viewed 27

I'm having some trouble testing some code which uses Jest fake timers. I have the below test written with Jest v29.0.3 to illustrate the issue:

  test('the test', () => {
    jest.useFakeTimers();

    const interval = setInterval(() => {
      console.info('timer');
    }, 1000);

    jest.advanceTimersByTime(1000);
    jest.advanceTimersByTime(1000);

    clearInterval(interval);

    jest.advanceTimersByTime(1000);
    jest.runOnlyPendingTimers();
  });

What I think this test should do is:

  1. Set Jest to use the fake timer functionality (https://jestjs.io/docs/timer-mocks#advance-timers-by-time).
  2. Create an interval which logs a message roughly every 1,000ms.
  3. Advances the interval by 2,000ms which causes two log messages to sent.
  4. Clears the interval so it doens't run any more.
  5. Advances any remaining timers by 1,000 ms (but no logs because interval is cancelled).
  6. Advances any remaining timers by 1 interval (but no logs because interval is cancelled).

What actually happens:

  1. Set Jest to use the fake timer functionality (https://jestjs.io/docs/timer-mocks#advance-timers-by-time).
  2. Create an interval which logs a message roughly every 1,000ms.
  3. Advances the interval by 2,000ms which causes two log messages to sent.
  4. Interval is not cancelled
  5. Advances any remaining timers by 1,000 ms (logs are logged).
  6. Advances any remaining timers by 1 interval (logs are logged).

As you can see, the issue is that I'm expecting the interval to be cancelled at step 4 however that does not appear to be the case.

  console.info
    timer

      at packages/sqs-consumer/test/message-heartbeat.spec.ts:61:15

  console.info
    timer

      at packages/sqs-consumer/test/message-heartbeat.spec.ts:61:15

  console.info
    timer

      at packages/sqs-consumer/test/message-heartbeat.spec.ts:61:15

  console.info
    timer

      at packages/sqs-consumer/test/message-heartbeat.spec.ts:61:15

Can you explain why this interval is not being cancelled and how I can test this kind of functionality?

0 Answers
Related