Search code examples
node.jsexpressjestjssupertest

why am getting server is already running on port 4000 even i have closed the server


I am running unit test with my node project using Jest library everything was working pretty fine. When I created new test for route authentication it starts showing server is already running on port 4000 even I am using afterEach() function to close the serve but don't know why am still getting server is already running on port 4000.

Even I have removed the new test for route authentication and restart my project by closing all the terminals but whenever I run the project it starts showing error that server is already running on port 4000.

Here is the code in user test file where am closing server properly and on the next test file I am again using same functions for server connection and closing.

const request = require("supertest");
const { Genre } = require("../../models/genre");
const { User } = require("../../models/user");
const mongoose = require("mongoose");

let server;

describe("/api/genres", () => {
  beforeEach(() => {
    server = require("../../index");
  });
  afterEach(async () => {
    server.close();
    await Genre.remove({});
  });

second test file code

const { User } = require("../../models/user");
const { Genre } = require("../../models/genre");
const request = require("supertest");
describe("auth middleware", () => {
  beforeEach(() => {
    server = require("../../index");
  });
  afterEach(async () => {
    await Genre.remove({});
    server.close();
  });

Here is the output of............................ ● auth middleware › should return 401 if no token is provided

listen EADDRINUSE: address already in use :::4000

  10 | 
  11 | const port = process.env.PORT || 4000;
> 12 | const server = app.listen(port, () =>
     |                    ^
  at Function.listen (node_modules/express/lib/application.js:618:24)
  at Object.<anonymous> (index.js:12:20)
  at Object.<anonymous> (tests/integration/auth.test.js:6:14)

Test Suites: 1 failed, 3 passed, 4 total Tests: 1 failed, 26 passed, 27 total Snapshots: 0 total Time: 13.606s Ran all test suites.

Index.js Code

const winston = require("winston");
const express = require("express");
const app = express();

require("./startup/logging")();
require("./startup/routes")(app);
require("./startup/db")();
require("./startup/config")();
require("./startup/validation")();

const port = process.env.PORT || 4000;
const server = app.listen(port, () =>
  winston.info(`Listening on port ${port}...`)
);
module.exports = server;

Solution

  • I am not an expert in Node.js, but the nature of your bug is very simple; you're trying to listen on a port that is already being listened on.

    This post offers a solid description of require(), which I believe is the source of your trouble.

    By calling require("../../index") in each of your test case programs, you are effectively exporting server twice, which results in two app.listen() calls.

    You would be infinitely better off exporting your server a single time to some main test program, in which you could then run all your test cases by calling require() on each of the test files. This approach is much better in the long run as well because adding additional test cases would 1000x easier; you could just write a new test script, export it to your main test program, and append it to your list of test cases.