I am pretty new to Nodejs and i am learning Nodejs course on udemy, I am facing some trouble of listen EADDRINUSE: address already in use :::4000
while re-running integration tests multiple time. The first time its successful but afterward I am getting the above-mentioned error on the following line
const server = app.listen(port, () => {winston.info(`Listening on port ${port}`)});
I am pasting my index.js and two test files, if some can point me out it will be a great help for me.
Index.js
const Joi = require("@hapi/joi");
Joi.objectId = require("joi-objectid")(Joi);
const winston = require("winston");
const express = require("express");
const app = express();
require("./startup/logging")();
require("./startup/config")();
require("./startup/dbconnectivity")();
require("./startup/routes")(app);
const port = process.env.port || 4000;
const server = app.listen(port, () => {winston.info(`Listening on port ${port}`)});
// exporting server object to be used in integration tests.
module.exports = server;
**Integration test file for Genre**
const request = require("supertest");
let server;
const {Genere} = require("../../models/genere");
const {User} = require("../../models/user");
describe("/api/genere", () => {
beforeEach(() => {
console.log("Before each Genre");
server = require("../../index");
});
afterEach(async () => {
console.log("After each Genre");
await Genere.deleteMany({});
await server.close();
});
describe("/GET", () => {
it("should return list of generes", async() => {
await Genere.insertMany([
{name: "genre1"},
{name: "genre2"},
{name: "genre3"}
]);
const res = await request(server).get("/api/geners");
expect(res.status).toBe(200);
console.log("response body is : " + res.body);
expect(res.body.length).toBe(3);
expect(res.body.map(g => g.name)).toContain("genre1");
});
});
describe("/GET/:id", () => {
it("should return genre with id", async() => {
const genre = new Genere({name: "genre1"});
await genre.save();
const res = await request(server).get("/api/geners/"+ genre.id);
expect(res.status).toBe(200);
expect(res.body.name).toBe("genre1");
});
it("should return error with invalid id", async() => {
const genre = new Genere({name: "genre1"});
await genre.save();
const res = await request(server).get("/api/geners/1");
expect(res.status).toBe(404);
expect(res.text).toMatch(/Invalid/);
});
});
describe("/POST", () => {
it("should return 401 if not authorized", async() => {
const genere = new Genere({name: "genere1"});
const res = await request(server).post("/api/geners").send(genere);
expect(res.status).toBe(401);
});
it("should return 400 if the name is less than 4 chars", async() => {
const res = await createRequestWithGenre({name: "g1"});
expect(res.status).toBe(400);
});
it("should return 400 if the name is greater than 25 chars", async() => {
const genreName = Array(26).fill("a").join("");
const res = await createRequestWithGenre({name: genreName})
expect(res.status).toBe(400);
});
it("should return 201 with gener object if proper object is sent", async() => {
const res = await createRequestWithGenre({name: "genre1"})
expect(res.status).toBe(201);
expect(res.body).toHaveProperty("_id");
expect(res.body).toHaveProperty("name", "genre1");
const genre = await Genere.find({ name: "genre1"});
expect(genre).not.toBe(null);
});
async function createRequestWithGenre(genre) {
const token = new User().generateAuthToken();
return await request(server)
.post("/api/geners")
.set("x-auth-token", token)
.send(genre);
}
});
});
As soon as i add another file for integration test like the one below i started to get the error which is mentioned after this file code.
const {User} = require("../../models/user");
const {Genere} = require("../../models/genere");
const request = require("supertest");
let token;
describe("middleware", () => {
beforeEach(() => {
console.log("Before each Middleware");
token = new User().generateAuthToken();
server = require("../../index");
});
afterEach(async () => {
console.log("After each Middleware");
await Genere.deleteMany({});
await server.close();
});
const exec = async() => {
return await request(server)
.post("/api/geners")
.set("x-auth-token", token)
.send({name: "gener1"});
}
it("should return 400 if invalid JWT token is sent", async() => {
token = "invalid_token";
const res = await exec();
expect(res.status).toBe(400);
expect(res.text).toBe("Invalid auth token");
});
});
Console Error
middleware
✕ should return 400 if invalid JWT token is sent (510ms)
● middleware › should return 400 if invalid JWT token is sent
listen EADDRINUSE: address already in use :::4000
10 | require("./startup/routes")(app);
11 | const port = process.env.port || 4000;
> 12 | const server = app.listen(port, () => {winston.info(`Listening on port ${port}`)});
| ^
13 | // exporting server object to be used in integration tests.
14 | module.exports = server;
at Function.listen (node_modules/express/lib/application.js:618:24)
at Object.<anonymous> (index.js:12:20)
at Object.beforeEach (tests/integration/middleware.test.js:11:22)
If someone can help me why it fails on the multiple runs then it will be really helpful for me to understand why do we need to open and close server object every time.