I am playing around vows and nodejs.
var vows = require('vows');
var http = require('http');
var suite = vows.describe('testing');
var host = 'www.google.com', port = '80', path = '/', method = 'GET';
suite.addBatch({
'A context': {
topic: function(){
http.get({
host: host,
port: port,
path: path,
method: method
}, this.callback);
},
"sample test": function(res, extra){//here extra is just to prevent vows error
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);//It never gets logged
});
console.log('HEADERS: ' + JSON.stringify(res.headers));//it is working
}
}
});
suite.export(module);
But I am unable to get the response body. What am I doing wrong.
I am using nodejs v 0.6.6 and vows v0.6.2
From what I can see, it looks like Vows doesn't directly invoke the test when this.callback
runs. It is delayed by processnextTick
. If I had to guess, maybe the 'data' event is being emitted during that time. That means you don't bind your 'data' function until after all the data events have been triggered.
Really though, the issue is that Vows tests are supposed to separate all async logic like this into the topic
itself. If you really want to check the chunks in a test, then do it like this.
Also note that you can have any number of chunks, there isn't just a single data
event. You may want to set the stream encoding, and join the data as strings. Your current code implicitly converts a Buffer to string, which can break for multi-byte characters.
suite.addBatch({
'A context': {
topic: function(){
var cb = this.callback;
var req = http.get({
host: host,
port: port,
path: path,
method: method
});
// Aggregate all chunks before running callback
req.on('response', function(res) {
var chunks = []
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
cb(null, res, chunks);
});
});
// Handle connection failures.
req.on('error', cb);
},
"sample test": function(err, res, chunks){
chunks.forEach(function (chunk, i) {
console.log('BODY piece ' + i + ': ' + chunk);
});
console.log('HEADERS: ' + JSON.stringify(res.headers));
}
}
});