Question

I can't test express apps on cloud9 with supertest : even basic tests throws ECONNREFUSED.

Steps to reproduce :

  • create a new nodejs workspace
  • npm install express supertest
  • create a file "fails.js" containing the following code :

    // Code from supertest page   
    var request = require('supertest')
    , express = require('express');
    var app = express();
    app.get('/user', function(req, res){
      res.send(201, { name: 'tobi' });
    });
    request(app)
    .get('/user')
    .expect('Content-Type', /json/)
    .expect('Content-Length', '20')
    .expect(201)
    .end(function(err, res){
       if (err) throw err;
     });
    

then launch node fails.js on terminal : Error: connect ECONNREFUSED

jmbarbier@test:~/606588 $ node fails.js
/var/lib/stickshift/522b68364382ecb9de0000ac/app-root/data/606588/fails.js:16
if (err) throw err
               ^
Error: connect ECONNREFUSED
at errnoException (net.js:906:11)
at Object.afterConnect [as oncomplete] (net.js:897:19)

I've no idea of what's going on...

======== EDIT

Thanks to accepted solution, here is the code to use mocha to test an express app on cloud9 or any environment restricting ip/port available : (works.js)

var request = require('supertest'), server;

before(function(done) {
    var express = require('express');
    var app = express();
    app.get('/user', function(req, res){
      res.send(201, { name: 'tobi' });
    });
    server = app.listen(process.env.PORT, process.env.IP, done);
});

after(function () {
    server.close()
})

describe("Testing /user", function() {
    it("Should return data", function(done) {
        request = request('http://' + process.env.IP + ':' + process.env.PORT);

        request.get('/user')
          .expect('Content-Type', /json/)
          .expect('Content-Length', '20')
          .expect(201)
          .end(function(err, res){
            if (err) throw err;
            done()
          });

    })


})

then mocha works.js ...

Was it helpful?

Solution

From a quick scan through of the code of supertest and vague knowledge on how Cloud9 works, it appears that the code you showed forces the Express application to choose a random port (if the application isn't already listening) and listen.

This won't work with Cloud9 because as far as I know, the assigned listen addresses are loopback addresses and are proxied to your project page. Instead, use this code:

var request = require('supertest')
var express = require('express');
var app = express();

app.get('/user', function(req, res) {
  res.send(201, { name: 'tobi' });
});

app.listen(process.env.PORT, process.env.IP);

This way, you assign a proper address and port to the Express application, and supertest won't assign a random port to it. Then use supertest like this:

request = request('http://' + process.env.IP + ':' + process.env.PORT);
request.get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '20')
  .expect(201)
  .end(function(err, res) {
    if (err) throw err;
  });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top