Jest runs test suites in parallel by default. However, the machine that the tests are running on only has a single port 3000 (or port 4000, etc.)
This means that if you tell your app to listen on a port, and then start multiple concurrent processes, there will be a port collision and Jest will exit with EADDRINUSE - port already in use
.
Like some people already mentioned, you can solve the issue by running your tests in sequence with --runInBand
. However, you will lose out on the performance benefits of parallelization.
There is another way... do not explicitly listen on a port when running tests.
if (process.env.NODE_ENV !== 'test') {
app.listen(port, () => console.log(`Listening on port ${port}`)
}
Now, when you feed your app to supertest, it will run your app on port 0 since it's not already running on a port.
const app = require('../app')
const request = require('supertest')
it('gets todos', async () => {
const response = await request(app).get('/todos')
expect(response.body.length).toEqual(3)
}
What exactly is port 0 you ask? That is how you tell Unix machines...
Choose the first randomly available port that you find.
Now that each test suite is running on a randomly available port, there is no longer a risk of port collisions which means we've solved the EADDRINUSE - port already in use
error and we can continue running tests in parallel.