PLEASE CHECK THIS REPO WITH THE EXAMPLES THAT YOU CAN RUN: https://github.com/apieceofbart/async-testing-with-jest-fake-timers-and-promises // Let's say you have a function that does some async operation inside setTimeout (think of polling for data) function runInterval(callback, interval = 1000) { setInterval(async () => { const results = await Promise.resolve(42) // this might fetch some data from server callback(results) }, interval) } // Goal: We want to test that function - make sure our callback was called // The easiest way would be to pause inside test for as long as we neeed: const pause = ms => new Promise(res => setTimeout(res, ms)) it('should call callback', async () => { const mockCallback = jest.fn() runInterval(mockCallback) await pause(1000) expect(mockCallback).toHaveBeenCalledTimes(1) }) // This works but it sucks we have to wait 1 sec for this test to pass // We can use jest fake timers to speed up the timeout it('should call callback', () => { // no longer async jest.useFakeTimers() const mockCallback = jest.fn() runInterval(mockCallback) jest.advanceTimersByTime(1000) expect(mockCallback).toHaveBeenCalledTimes(1) }) // This won't work - jest fake timers do not work well with promises. // If our runInterval function didn't have a promise inside that would be fine: function runInterval(callback, interval = 1000) { setInterval(() => { callback() }, interval) } it('should call callback', () => { jest.useFakeTimers() const mockCallback = jest.fn() runInterval(mockCallback) jest.advanceTimersByTime(1000) expect(mockCallback).toHaveBeenCalledTimes(1) // works! }) // What we need to do is to have some way to resolve the pending promises. One way to do it is to use process.nextTick: const flushPromises = () => new Promise(res => process.nextTick(res)) // IF YOU'RE USING NEW JEST (>27) WITH MODERN TIMERS YOU HAVE TO USE A SLIGHTLY DIFFERENT VERSION // const flushPromises = () => new Promise(jest.requireActual("timers").setImmediate) it('should call callback', async () => { jest.useFakeTimers() const mockCallback = jest.fn() runInterval(mockCallback) jest.advanceTimersByTime(1000) await flushPromises() expect(mockCallback).toHaveBeenCalledTimes(1) })