1

I have a server.js module that exports a start() function to start my server. I require this module and start the server from index.js.

I'm trying to unit test the server.js module in isolation (with Mocha) by starting the server in a child_process.fork call but I don't see how to call the exported start function.

It's currently working by passing 'index.js' to the fork call but then I don't see how to pass options through to the server.js module (sending a port number for example).

Here's my server.js and the unit test that uses index.js (which only requires and calls server.start()).

I'd like to test server.js directly so I can pass environment variables to it.

====EDIT====

I'm not sure what I thought I would gain by starting the server in a separate process.
I've changed the test to just start the server in the before block.
Suggestions welcome.

var assert = require("assert");
var request = require("request");

describe("Server", function(){
  var server;
  var port = 4008;

  before(function(done){
    server = require("../server");
    server.start(port);
    done();
  });

  it('listens on specified port (' + port + ')', function(done){
    request('http://localhost:' + port, function(err, res, body){
      assert(res.statusCode == 200);
      done();
    });
  });

});
1
  • If you don't need to spawn processes for your tests, then this question should probably be closed as too localised. Commented Jan 11, 2013 at 0:02

1 Answer 1

1

You may want to use the cluster module for this, which makes handling processes a little simpler. The following may be along the lines of what you need.

var cluster = require('cluster');

// Runs only on the master process.
if (cluster.isMaster) {
    var environmentVariables = { PORT: 2020 };

    var worker = cluster.fork(environmentVariables);

    // Catch a message from the worker, and then destroy it.
    worker.on('message', function(message) {
        if (message.hasOwnProperty('testResult')) {
            // Kill the worker.
            worker.destroy();

            // Then do something with the result.
        }
    });
}

// Runs only on a worker process.
if (cluster.isWorker) {
    var server = require('./server');

    server.start();

    // Do some stuff for tests.

    // Send the test result.
    process.send({ testResults: 'pass', failReason: null });
}

I haven't tested this, but hopefully the gist is clear. You can pass in custom environment variables when the worker process is spawned, and then have the worker process message the master with the result. You probably need to handle exit events and a time out for when the worker crashes or hangs up.

As an aside, you should probably be wrapping the process.env.PORT in a parseInt.

Sign up to request clarification or add additional context in comments.

1 Comment

If I stick all the testing code in the worker process, that doesn't seem any different than just putting the "var server = require('../server'); server.start();" in mocha's before block. They'll be running in the same process. Which, I've come to think is fine. I'm not sure why I wanted to keep the server in a separate process.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.