Something keeps Node's event loop alive after the tests finish. These open resources are called open handles. Common ones:
- an open database pool
- a Redis or message broker connection
- an HTTP server that was started and never closed
- a
setInterval - a scheduler that registered itself when a module was imported
To find them, run jest --detectOpenHandles. It shows where each handle was created, and it works best with --runInBand.
Then close everything in afterAll:
await app.close()for a Nest appawait dataSource.destroy()await redis.quit()server.close()- clear any intervals
Also make background schedulers switch off in tests. Call unref() on timers that shouldn't keep the process alive.
--forceExit makes the message go away, but it only hides the leak. The leftover resources can still interfere with other tests in the same worker.
- Open handles keep Node's event loop alive after the tests finish.
- Find open handles with
--detectOpenHandles. - Close the app, database, Redis, servers and timers in
afterAll. --forceExithides the leak instead of fixing it.
Read more