How to test a clustered Express app with Mocha?

express, node.js

Solution

It's been quite a long time since I have posted this question. Since no one has answered, I will answer to this question myself.

I kept the /index.js as it is:

module.exports = process.env.CODE_COV
    ? require('./lib-cov/app')
    : require('./lib/app');

In /lib/app.js which starts the cluster, I have the following code. In brief, I start the cluster only in non-test environment. In test environment the cluster is not started but only one app/worker itself is started as defined in the `cluster.isMaster && !module.parent.parent` condition.

var cluster = require('cluster'),
    express = require('express'),
    app = module.exports = express.createServer();

if (cluster.isMaster && !module.parent.parent) {
    // Considering I have 4 cores.
    for (var i = 0; i < 4; ++i) {
        cluster.fork();
    }
} else {
    // do app configurations, then...

    // Don't listen to this port if the app is required from a test script.
    if (!module.parent.parent) {
        app.listen(8080);
    }
}

In the above case `!module.parent.parent` will be evaluated as a truthful object only if the application was not started by a test script.

- `module` is the current /lib/app.js script.

- `module.parent` is its parent /index.js script.

- `module.parent.parent` is `undefined` if the application was started directly via `node index.js`.

- `module.parent.parent` is the test script if the application was started via one of the scripts.

Thus, I can safely start the script where I can set a custom port.

/test/test1.js

var app = require('../');

app.listen(7777);

// send requests to app, then assert the response.

At the same time if I need to run the application in real, i.e. not for testing, then I run `node index.js` and it will start up the cluster of applications.

Problem

Here is a simplified version of my cluster Express app: /index.js ``` module.exports = process.env.CODE_COV ? require('./lib-cov/app') : require('./lib/app'); ``` /lib/app.js ``` var cluster = require('cluster'), express = require('express'), app = module.exports = express.createServer(); if (cluster.isMaster) { // Considering I have 4 cores. for (var i = 0; i < 4; ++i) { cluster.fork(); } } else { // do app configurations, then... // Don't listen to this port if the app is required from a test script. if (!module.parent.parent) { app.listen(8080); } } ``` /test/test1.js ``` var app = require('../'); app.listen(7777); // send requests to app, then assert the response. ``` Questions: - `var app = require('../');` will not work in this cluster environment. Which of the worker apps should it return? Should it return the cluster object instead of an Express app? - Now, obviously setting the port in the test script will not work. How would you set a port within a test script to a cluster of apps? - How would you send requests to this cluster of apps? The only solution I can think of is to conditionally turn off the clustering feature and run only one app if the app is requested from a test script (`if (module.parent.parent) ...`). Any other way to test a clustered Express app with Mocha?

Original source