Reputation: 65373
I've written a handler for http.Server
's request event (i.e. a function with signature function (request, response) { ... }
) and I'd like to test it. I'd like to do this via mock http.ServerRequest
and http.ServerResponse
objects. How can I create these?
The obvious way doesn't seem to work:
$ node
> var http = require('http');
> new http.ServerRequest();
TypeError: undefined is not a function
at repl:1:9
...
Do I need to test this via a "real" HTTP server and client?
Upvotes: 0
Views: 5317
Reputation: 4079
I created a simple and basic mock for http.ServerResponse
, the gist is here and for http.ServerRequest
I use rewire.
Firstly load dependencies:
var require = require('rewire'),
events = require('events'),
util = require('util');
This is the http.ServerResponse
mock. It basically creates an object with the same methods as http.ServerResponse, and then the events
module is inherited using the util
module.
/**
* Mock https.serverResponse
* @type {Object}
*/
var mockResponse;
Eventer = function(){
events.EventEmitter.call(this);
this.data = '';
this.onData = function(){
this.emit('data', this.data);
}
this.setEncoding = function(){
}
this.onEnd = function(){
this.emit('end', this.data);
}
this.run = function(){
this.onData();
this.onEnd();
}
};
util.inherits(Eventer, events.EventEmitter);
I then use this mock with rewire to override the http module's get(), request() or any other library.
/**
* Mocks literal object for rewire mocking.
* @see https://github.com/jhnns/rewire
* @type {Object}
*/
var mocks = {
"https" : {
"get" : function(url, fn){
fn(mockResponse.data);
mockResponse.run();
}
}
};
//instead of: var myModule = require('myModule');
//do:
var myModule = rewire('myModule');
myModule.__set__(mocks);
Now the http
library in your module is mocked
Upvotes: 0
Reputation: 65373
There's at least two projects that allow mocking of http.ServerRequest
and http.ServerResponse
: https://github.com/howardabrams/node-mocks-http and https://github.com/vojtajina/node-mocks.
And for some reason it does seem to be more common to test via real HTTP request; https://github.com/flatiron/nock seems to be the tool to use here.
See also node.js: Mock http request and response.
Upvotes: 4
Reputation: 48013
Yes, you can do it using http.request. It allows you to issue requests from server, so you can test it with your code. If you want to send simple GET request you can use http.get , which is easier. Otherwise you would have to construct your request yourself. Example from docs :
var options = {
host: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST'
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
console.log('STATUS: ' + res.statusCode);
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write('data\n');
req.end();
If you are using request you can do the same.
var request = require('request');
request.post( url, json_obj_to_pass,
function (error, response, body) {
if (!error && response.statusCode == 200)
console.log(body)
}
);
Upvotes: 0