Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to test a Node.js Server process using Mocha

Fairly new to Node.js

Made an app that runs a server process and serve files (does not use express or any frameworks), Now I'm trying to unit test it.

I'm trying to use a mocha test for that... I intended to start my server process and then run requests against it to test the expected results (stats code, body content and the likes)

However it's not working properly, all the request fail to connect to the server... I'm pretty sure that the issue is because node is juts running one process loop, the server is not running "in the background" while the queries run or possibly the server is not running yet (started ASYNC) while the request are being made ?

Anyway I was wondering what was the proper way to test this, I assume that either I need to have the server run in the background (like a forked process) and/or maybe I need to find a way to wait for the server process to be "up" first but not sure how.

Or at least recommendations on testing such server process (with Mocha or other).

Thanks.

Here is example test code (Updated since original question)

var server = new Server302('./fixture/');

var instance;

describe('Tests', function() {

before(function(done) {
     instance = http.createServer(function(request, response) {
        console.log(request.url);
        server.serve(request, response);
    }).listen(8000);
    instance.on("listening", function() {
        console.log("started");
        done();
    });
});

after(function(done){
  instance.close();
  console.log("stopped");
  done();
});

it("Should fetch test.html", function(done) {
    console.log("test1");
    http.get("http://localhost:8000/", function(res) {
        res.on('data', function(body) {
            console.log(body)
            expect(body).toEqual("test");
            done();
        });
    })
});

It seem to Execute in order but still fails with a connection error, whereas it works when testing manually with the browser:

started
test1
․․․stopped


  ✖ 1 of 1 tests failed:

  1) Tests Should fetch test.html:
  Error: connect ECONNREFUSED
  at errnoException (net.js:670:11)
  at Object.afterConnect [as oncomplete] (net.js:661:19)
like image 501
Thibaut Colar Avatar asked Aug 19 '12 23:08

Thibaut Colar


2 Answers

In your before don't call done until you get the "listening" event fired by the server.

before(function(done) {
    instance = http.createServer(function(request, response) {
        console.log(request.url);
        server.serve(request, response);
    }).listen(8000);
    instance.on("listening", function() {
        console.log("started");
        done();
    });
});

That should ensure your test connections don't start before the server is ready.

See also the documentation for server.listen

like image 156
Peter Lyons Avatar answered Oct 19 '22 20:10

Peter Lyons


Also had to deal with the body coming in chunks, here is the final thing that works, in case that helps somebody else:

var Server302 = require('../lib/server302.js'),
http = require('http'),
assert = require("assert");

var server = new Server302('./fixture/');

var instance;

describe('Tests', function() {

before(function(done) {
    instance = http.createServer(function(request, response) {
        server.serve(request, response);
    }).listen(8100);
    instance.on("listening", function() {
        done();
    });
});

after(function(done) {
    instance.close();
    done();
});

it("Should fetch test.html", function(done) {
    console.log("test1");
    var body = "";
    http.get({host: "localhost", port:8100, path: "/"}, function(res) {
        res.on('data', function(chunk) {
            // Note: it might be chunked, so need to read the whole thing.
            body += chunk;
        });
        res.on('end', function() {
            assert.ok(body.toString().indexOf("<a href='/dummy.txt'>") !== -1);
            assert.equal(res.statusCode, 200);
            done();
        });
    })
});

it("Should fetch dummy.txt", function(done) {
    http.get({host: "localhost", port:8100, path: "/dummy.txt"}, function(res) {
        res.on('data', function(body) {
            assert.equal(res.statusCode, 200);
            assert.ok(body.toString().indexOf("test") === 0);
            done();
        });
    });
});

it("Should get 404", function(done) {
    http.get({host: "localhost", port:8100, path: "/qwerty"}, function(res) {
        assert.equal(res.statusCode, 404);
        done();
    });
});

});
like image 30
Thibaut Colar Avatar answered Oct 19 '22 22:10

Thibaut Colar