JEST with Supertest getting instance already in use error - need to restart the whole test server

Viewed 311

I make two 'supertest' requests one after each other like so:

const request = require('supertest');
const server = require('@bin/www');

it('should do something', async () => {

  // prepare data
  const data = { ... some data }
  
  // create business
  const res = await request(server)
  .post('/v2/businesses')
  .send({
    ...data
  });

  // store the returned business id
  const b_id = res.body.data.id;

  // now the critical point - to make another http request to the api,
  // in order to fetch the business and expect it to be defined.
  const res1 = await request(server)
    .get('/v2/businesses')
    .query({
      b_id
    });

  // expectations...
  expect(res.body.data.business).toBeDefined();
});

The test passes on first time, after pressing "Enter" to test again, I got the following error:

listen EADDRINUSE: address already in use :::3002

The only solution is to kill the whole test process and start it all over again. The error also occurs on different test suites as well.

This is the command to run the tests using JEST (in the package.json):

"test": "jest --forceExit --detectOpenHandles  --watchAll --maxWorkers=1"

But this doesn't work as expected.

There are the imported files from where the server object comes from:

// bin/www
var app         = require('@app/app');
var server      = require('@app/server');

server.listen(... some callback)

module.exports = app;

// app/app
var app = require('express')();

module.exports = app;

// app/server
var app = require('@app/app');
var server = require('http').createServer(app);

module.exports = server;

As I understand, the server is probably keep running even after the test finishes, then when firing another test, the server status is already active and in use, so therefore this error.

How can I close the server after each test?

I have tried:

afterEach(() => server.close())

But got an error that server.close is not a function.

1 Answers

Just use conditional listen:

// Turn off listen, when you are testing
if (process.env.NODE_ENV !== "test") {
  app.listen(process.env.PORT || 4000);
}

Jest using special NODE_ENV, that called test, so you don't need an listen method. Also supertest is providing unical port for every app instance.

Related