How can I unit test the request response cycle in Node.js?

Problem

For example suppose I have the following

app.get('/', function(req, res) {
    var ip;
    if(req.headers['x-forwarded-for']){
        ip = req.headers['x-forwarded-for'];
    }
    else {
        ip = req.connection.remoteAddress;
    }
});

I would like to unit test to see whether ip is being properly retrieved. One way is as follows

function getIp(req) {
    var ip;
    if(req.headers['x-forwarded-for']){
        ip = req.headers['x-forwarded-for'];
    }
    else {
        ip = req.connection.remoteAddress;
    }
    return ip;
}

app.get('/', function(req, res) {
    var ip = getIp(req);
});

Now I have a function getIp that I can unit test. However I'm still stuck. How can I feed a simulated req object into getIp?

Problem courtesy of: deltanovember

Solution

I would just write integration-tests for that. Node.js is fast enough for that. Especially when you use something like Mocha's watch-mode. You could use something like superagent or request to perform http requests.

There is also something like for example nock to mock out your http requests. Although I have never used it because integration-tests test the real thing and are fast enough for my tast.

Solution courtesy of: Alfred

Discussion

I'd recommend using mocha to write your unit tests in which case you'll use 'request' as your http client. But the simplest way to get started is to use the following:

var http = require('http');
//Change to the ip:port of your server
var client = http.createClient(3000, 'localhost'); 

var request = client.request('GET', '/',
  {'host': 'localhost'});
request.end();
request.on('response', function (response) {
  console.log('STATUS: ' + response.statusCode);
  console.log('HEADERS: ' + JSON.stringify(response.headers));
  response.setEncoding('utf8');
  response.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});
Discussion courtesy of: Rudolf Meijering

This recipe can be found in it's original form on Stack Over Flow.