kjs3
kjs3

Reputation: 6178

Node.js calling function on child_process.fork

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();
    });
  });

});

Upvotes: 1

Views: 1584

Answers (1)

qubyte
qubyte

Reputation: 17748

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.

Upvotes: 1

Related Questions