1

I'm using supertest to unit test my server configurations and route handlers. The server configurations tests are in test.server.js and the route handling tests are in test.routes.handlers.js.

When I run all the test files using mocha ., I get EADDRINUSE. When I run each file individually, everything works as expected.

Both files define and require supertest, request = require('supertest'), and the express server file, app = require('../server.js'). In server.js, the server is started like so:

http.createServer(app).listen(app.get('port'), config.hostName, function () {
  console.log('Express server listening on port ' + app.get('port'));
});

Is there something wrong in my implementation? How can I avoid EADDRINUSE error when running my tests?

M.K. Safi
  • 6,560
  • 10
  • 40
  • 58

2 Answers2

4

mocha has a root Suite:

You may also pick any file and add "root" level hooks, for example add beforeEach() outside of describe()s then the callback will run before any test-case regardless of the file its in. This is because Mocha has a root Suite with no name.

We use that to start an Express server once (and we use an environment variable so that it runs on a different port than our development server):

before(function () {
  process.env.NODE_ENV = 'test';
  require('../../app.js');
});

(We don't need a done() here because require is synchronous.) This was, the server is started exactly once, no matter how many different test files include this root-level before function.

Try requiring supertest from within a root level before function in each of your files.

Dan Kohn
  • 33,811
  • 9
  • 84
  • 100
  • 1
    After you require `app.js`, don't you need to pass the returned object to `supertest`? My understanding is that supertest needs to have your server as its first argument, i.e. `var request = require('supertest'); var app = require('../../app.js'); request = request(app);` and only then can you do `request.get('/')` or whatever. So how are you passing `app` to supertest in the other files? I guess I'm gonna try and make a unique global variable and pass that... – M.K. Safi Sep 14 '13 at 16:29
  • What worked for me is moving the `require` statements for supertest and app to the very top, outside `before` and `describe` in both files. – M.K. Safi Sep 14 '13 at 16:51
1

Answering my own question:

My supertest initialization looks like this:

var app = require('../server.js');
var request = require('supertest')(app);

In test.server.js, I had these require statements directly inside a describe. In test.routes.handlers.js, the statements were inside a before inside a describe.

After reading dankohn's answer, I was inspired to simply move the statements to the very top outside any describe or before and the tests all run without problems now.

Community
  • 1
  • 1
M.K. Safi
  • 6,560
  • 10
  • 40
  • 58