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:
- Set Jest to use the fake timer functionality (https://jestjs.io/docs/timer-mocks#advance-timers-by-time).
- Create an interval which logs a message roughly every 1,000ms.
- Advances the interval by 2,000ms which causes two log messages to sent.
- Clears the interval so it doens't run any more.
- Advances any remaining timers by 1,000 ms (but no logs because interval is cancelled).
- Advances any remaining timers by 1 interval (but no logs because interval is cancelled).
What actually happens:
- Set Jest to use the fake timer functionality (https://jestjs.io/docs/timer-mocks#advance-timers-by-time).
- Create an interval which logs a message roughly every 1,000ms.
- Advances the interval by 2,000ms which causes two log messages to sent.
- Interval is not cancelled
- Advances any remaining timers by 1,000 ms (logs are logged).
- 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?