sindresorhus / p-queue

Promise queue with concurrency control
MIT License
3.39k stars 182 forks source link

How can I use jest fake timers when testing code that use p-queue? #193

Open bluprince13 opened 1 year ago

bluprince13 commented 1 year ago

I am trying to test my code that makes use of p-queue.

However, I don't want my test to actually wait for seconds. I tried to use https://jestjs.io/docs/timer-mocks.

jest.useFakeTimers();

I also tried to mock setTimeout myself

       const setTimeoutCopy = setTimeout
       let waitingTime = 0
       jest.spyOn(global, "setTimeout").mockImplementation((f, ms) => {
            waitingTime += ms
            return setTimeoutCopy(f, 0)
        })

However, this seems to have no effect on p-queue.

And my test times out with:

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."

Would appreciate some guidance.

arantespp commented 1 month ago

I solved this following this recommendation.

I've removed await from my method and added await jest.runAllTimersAsync(); await flushPromises();

const flushPromises = () => {
  // Wait for promises running in the non-async timer callback to complete.
  // From https://stackoverflow.com/a/58716087/308237
  return new Promise((resolve) => {
    return setImmediate(resolve);
  });
};

test('my test', async () => {  
  myAsyncMethod();

  await jest.runAllTimersAsync();

  await flushPromises();

  expect(true).toBe(true);
});