supertest: Error: listen EADDRINUSE: address already in use :::3000

Hey guys, so I have been just trying to start testing my Koa server using Supertest.

I am getting the error: Error: listen EADDRINUSE: address already in use :::3000

I have tried closing everything down on that port and run it but I’m still getting the issue.

Here is my app:

require('dotenv').config();
const Koa = require('koa');
const app = new Koa();
const router = require('./router');
const PORT = process.env.NODE_PORT || 3001;
const ENV = process.env.NODE_ENV || 'Development';
const logger = require('koa-logger');

app.use(logger());
app.use(router.routes());

app.listen(PORT, (err) => {
    if (err) console.error('❌ Unable to connect the server: ', err);
    console.log(`🌍 Server listening on port ${PORT} - ${ENV} environment`);
  });

    module.exports = app;

my router:

const Router = require('koa-router');
const router = new Router();

router.get('/', ctx => ctx.body = 'Sending some JSON');
  module.exports = router;

finally the test:

const server = require('../index');
const request = require('supertest').agent(server.listen());

afterEach(() => {
  server.close();
});

describe('routes: index', ()=> {
  it('should reach endpoint', async () => {
    const response = await request(server).get('/');
   
    expect(response.status).toEqual(200);
    expect(response.body).toEqual('Sending some JSON');
  });
});

my server isn’t even running on port 3000 it is running on 8080 however, just to make sure I will run my server on 3000 and it starts up no problem. I then try to run the test, I get the error again with the server running on 3000 and the server not. Kinda stuck

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 3
  • Comments: 46 (1 by maintainers)

Most upvoted comments

lsof -i:3000 
kill -9 [PID] 

So I had this issue as well. What you want to do is that you don’t want to start your server. In your main server express file you should export the server. But do NOT call the listen method.

So modify your code so that when you’re testing (for example by setting an environment variable and looking for that), you’re not calling the listen() method. This should resolve it and let you run your tests in parallel.

Could you send us the output of: lsof -i:3000

I had that exact error message, try this out:

Expected: I can use app.listen(PORT, ()=>{})

Code: index.js exports “app”, app.listen(PORT, ()=>{}) is uncommented

Output: npm test => “Jest did not exit one second after the test run has completed. This usually means that there are asynchronous operations that weren’t stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.”

Workaround: comment/delete app.listen(PORT) and listen to the port on another file (example: require “app” from index.js in app.js and listen to a port in app.js)

You are actually running the main server in the terminal. Stop the server so the debugger can run on the same PORT

@HashemDeveloper when you run lsof -i:3000, you will get some information related to the port. the second column in the returned table says PID, that’s what you have to type instead of [PID] when run kill -9

Looks like you have to do two things:

  1. ensure that the app has not yet been started (i.e. put the app.listen in an if statement that asserts it’s not in test mode first)
  2. pass koa.callback() into supertest as follows:
request(app.callback())

what’s weird is that the documentation claims “if the server is not already listening for connections then it is bound to an ephemeral port for you so there is no need to keep track of ports.”

To fix this you need to avoid calling app.listen() when you run tests. There are 2 questions on StackOverflow with various solutions:

In summary, one solution is to wrap app.listen():

if (process.env.NODE_ENV !== 'test') {
    app.listen(port)
}

And another solution is to organize your code so that app.listen() is placed in a different file than app:

Thanks a lot @aech12 and @spock123 you saved my day!

@Abdelrahmanyassin786 In your terminal window, where you are running your application; run this command: lsof -i:3000 It will return some information related to process running; look for the PID number. next, run kill -9 [PID], but replace [PID] with the PID number from the first command. That will kill the process completely, and you will be able to start it again.

UPDATE so the reason was because in my app.test.js file I had a series of tests that were not closing after completion because I was running tests like:

const app = require('../index');

describe('server working', () => {
  
  it('should exist', async (done)=> {
    expect(app).toBeDefined();
    done();
  });

  it('should be an object', async (done)=>{
    expect(typeof app).toBe("object");
    done();
  });
});

and I am still getting the error:

Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren’t stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.

I have the same issue, solution that I found is go to node_modules find nodemon/monitor/run. And there is variable “killedAfterChange” in my case var killedAfterChange = false; i changed to var killedAfterChange = true; and it’s worked fine

Sometimes, when i press save and the server restarts i get the same error.