If you have a Jest test that calls setTimeout
and Promise
:
// timeout-promise.test.js
jest.useFakeTimers();
const utils = {
async timeout(seconds) {
await Promise.resolve((resolve) => setTimeout(resolve, seconds * 1000));
},
};
it('waits 1 second', async () => {
await utils.timeout(1);
// ...
});
The test will fail with the error:
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
The solution is to remove jest.useFakeTimers
and stub out timeout
with jest.spyOn
:
// timeout-promise.test.js
-jest.useFakeTimers();
const utils = {
async timeout(seconds) {
await Promise.resolve((resolve) => setTimeout(resolve, seconds * 1000));
},
};
it('waits 1 second', async () => {
+ const timeoutSpy = jest.spyOn(utils, 'timeout').mockResolvedValueOnce();
await utils.timeout(1);
// ...
+ timeoutSpy.mockRestore();
});
The updated test code will now pass:
// timeout-promise.test.js
const utils = {
async timeout(seconds) {
await Promise.resolve((resolve) => setTimeout(resolve, seconds * 1000));
},
};
it('waits 1 second', async () => {
const timeoutSpy = jest.spyOn(utils, 'timeout').mockResolvedValueOnce();
await utils.timeout(1);
// ...
timeoutSpy.mockRestore();
});