3

Is it possible to configure jest to await any pending promises before exiting, to avoid log noise caused by pending code being called after the last test is finished, at which point jest will have torn down the environment?

I have an application which starts by initializing some services asynchronously. If calls are made to these services, the pending background work will first be awaited, and then the task executed. If no calls are made however, the services will invisibly be running init code in the background that no-one cares about.

The problem arises when my tests finish too quickly; if this happens before this pending init work is done, strange things happen - my log gets full of noise which I at first couldn't at all understand - calls like JSON.stringify would fail with cannot access JSON of object null, which turned out to be because jest had torn down the environment so that the global object, containing symbols like JSON was now null (_environment.global.JSON).

I can add an afterAll() hook that simply waits for a second or so, but this seems ugly, and also adds the question what kind of delay is needed; this might break randomly if initialization sometimes takes 100 ms and sometimes 1100 ms.

I could of course add code to afterAll() that makes dummy service calls simply to guarantee that any pending initialization is awaited.

But I would rather like a general, configuration based approach to this, if there is one?

So, is there a way to tell jest to await all pending promises, either before tests start or after? Or is there a way to tell jest to add a grace period at the end, after all tests, without having to resort to a manual afterAll() call (which must be placed in a file which all tests import, to still have it working properly if only running some tests etc)?

This question actually asks the same question, but the answer with 177 upvotes doesn't do what the question asked for - it simply awaits any promises that are already fulfilled but not handled by the micro tasks queue yet. It does not await any promises that are still pending.

JHH
  • 8,567
  • 8
  • 47
  • 91
  • Have you tried `flush-promises`? I use it in pretty much every project and it seems to do exactly what you are asking for. Just call `await flushPromises()` in an `afterAll` hook or anywhere in your tests. Also useful if you want to test if proper API calls have been made after a component is mounted. https://www.npmjs.com/package/flush-promises – aside May 27 '21 at 10:36
  • 1
    Thanks @aside, no I hadn't, but looking at its source code, it's just a wrapper for `await new Promise(setImmediate)`, so I'm pretty sure it would also simply await all currently fulfilled promises (by letting the event loop process everything already in the queue), not all pending promises. – JHH May 27 '21 at 10:54

0 Answers0