Why does this test work with legacy fake timers and not with the default modern fake timers from jest?
jest.useFakeTimers({ legacyFakeTimers: true }); // Works
// jest.useFakeTimers(); // Doesn't work
it('simpleTimer', async () => {
async function simpleTimer(callback) {
await callback();
setTimeout(() => {
simpleTimer(callback);
}, 1000);
}
const callback = jest.fn();
await simpleTimer(callback);
for (let i = 0; i < 8; i++) {
jest.advanceTimersByTime(1000);
await Promise.resolve(); // allow any pending jobs in the PromiseJobs queue to run
}
expect(callback).toHaveBeenCalledTimes(9); // SUCCESS
});
I got it from: https://stackoverflow.com/a/52196951, I've tried almost every answer in that post, and others like this one: Jest fake timers with promises.
Using the modern one just blocks the terminal until ^C is input/sent.
Other things that I've tried:
// 1
const flushPromises = () => new Promise(setImmediate);
// 2
const timeout = (ms) => // To wait like `await timeout(1000)`
new Promise(resolve => {
setTimeout(resolve, ms)
});
// 3
await new Promise(process.nextTick);
I'm running out of ideas and places keywords to search.
I'm using:
- Node.JS: v18.15.0;
- Jest: v29.5.0;
With a setup file that contains only: jest.useFakeTimers()
.
So I realized that I had jest.useFakeTimers()
both in setup file and test file. So I removed it from the setup file and left only one.
After that, I got another message:
thrown: "Exceeded timeout of 5000 ms for a test. Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."
Changed again to jest.useFakeTimers({ legacyFakeTimers: true })
and worked as expected.