I'm creating a testing for my express app. The project has multiple test files. In each module the server instance is required at beforeEach() method and closed at afterEach() method. but after testing one or two of the modules it'll raise address already in use and jest won't terminate.
beforeEach(() => {
server = require('./../../../bin/www')});
afterEach(async() => {
server.close();
/**
* database cleanup logic goes here.
*/
});
I want jest to terminate after all the test suites are completed.
Just 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.
I had this issue, and seem to have solved it by setting jest to only use one worker. I think the issue was caused by more than one instance of the server running with the same port, thereby causing the clash.
This is the line from my npm package.json file. The --maxWorkers=1
seems to have done the trick (https://jestjs.io/docs/en/cli#maxworkers-num-string).
"scripts": {
"test": "jest --forceExit --detectOpenHandles --watchAll --maxWorkers=1"
},
the very basic thing to do is to put your app.listen() inside some other file , other than your file that consists all the routes . for example : index.js
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
app.use(bodyParser.json());
const students = ["Elie", "Matt", "Joel", "Michael"];
app.get("/", (req, res) => {
return res.json(students);
});
module.exports = app;
and server.js
const app = require("./index");
app.listen(3000, () => console.log("server starting on port 3000!"));
In this way Jest will not be reading app.listen() at all . cheers !
I'm using, node express server 4.16.2. If you're using a different version this may not apply to you.
In your describe block when you're closing the server, await
for it.
describe('auth midleware', () => {
// loading the server
beforeEach(() => {>
server = require('../../../index')
});
// closing the server
afterEach(async () => {
await server.close();
});
// the tests will go here
});
Also after you do this, run your node application in the command line.
node index.js
Check your package.json, how your script test tag is named. Mine is test.
{ ...
"scripts": {
"test": "jest --verbose --coverage --forceExit --watchAll --maxWorkers=1"
}
...
}
After that run your test again.
npm test
There is also an option --runInBand to run tests one by one.
server = require('./../../../bin/www')});
afterEach(async() => {
await server.close();
you just have make it await to close the server properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With