I have a TypeScript async function which must perform a sleep of 1 second between two statements. It is implemented by this code.
async function systemUnderTest(): Promise<void> {
console.log("One");
await new Promise(r => { setTimeout(r, 1000); });
console.log("Two");
}
I want to test it using the Jest framework. I can run this test:
test('myTest', async () => {
await systemUnderTest();
});
It works, but it uses real time. How can I test that function in fake time?
I tried to write this test:
test('myTest', async () => {
jest.useFakeTimers();
await systemUnderTest();
jest.runAllTimers();
jest.useRealTimers();
});
For it, the timeout of 5 seconds is exceeded, and it never prints "Two".
Can you try to:
test('myTest', async () => {
jest.useFakeTimers();
const promise = systemUnderTest(); // start the function without awaiting it
jest.runAllTimers(); // this will run the setTimeout in systemUnderTest
await promise; // now we can wait for the function to finish
jest.useRealTimers();
});
Note that when using fake timers, the setTimeout callback will be executed synchronously when you run jest.runAllTimers(), so there's no need to await it beforehand.