Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TDD/ testing with streams in NodeJS

I've been trying to find a reasonable way to test code that uses streams. Has anyone found a reasonable way/ framework to help testing code that uses streams in nodejs?

For example:

var fs = require('fs'),     request = require('request');  module.exports = function (url, path, callback) {   request(url)     .pipe(fs.createWriteStream(path))     .on('finish', function () {       callback();     }); }; 

My current way of testing this type of code either involves simplifying the code with streams so much that I can abstract it out to a non-tested chunk of code or by writing something like this:

var rewire = require('rewire'),     download = rewire('../lib/download'),     stream = require('stream'),     util = require('util');  describe('download', function () {   it('should download a url', function (done) {     var fakeRequest, fakeFs, FakeStream;      FakeStream = function () {       stream.Writable.call(this);     };      util.inherits(FakeStream, stream.Writable);      FakeStream.prototype._write = function (data, encoding, cb) {       expect(data.toString()).toEqual("hello world")       cb();     };      fakeRequest = function (url) {       var output = new stream.Readable();        output.push("hello world");       output.push(null);        expect(url).toEqual('http://hello');        return output;     };      fakeFs = {       createWriteStream: function (path) {         expect(path).toEqual('hello.txt');         return new FakeStream();       }     };      download.__set__('fs', fakeFs);     download.__set__('request', fakeRequest);      download('http://hello', 'hello.txt', function () {       done();     });    }); }); 

Has anyone come up with more elegant ways of testing streams?

like image 908
Michael Wasser Avatar asked Apr 17 '14 18:04

Michael Wasser


People also ask

What is TDD in NodeJS?

Test driven development(TDD) is an iterate process that begins with writing a test code for an application or function before starting out to write the application. The next steps entails writing and refactoring the application until it passes the test code.

How is node js used in testing?

NodeJS Unit testing is the method of testing small pieces of code/components in isolation in your NodeJS application. This helps in improving the code quality and helps in finding bugs early on in the development life cycle.

Is it possible to write test in node JS?

If you've ever written tests for a Node. js application, chances are you used an external library. However, you don't need a library to run unit tests in Javascript. This post is going to illustrate how to make your own simple testing framework using nothing but the standard library.

What is stream in NodeJS in what cases stream should be used?

Streams are one of the fundamental concepts that power Node. js applications. They are data-handling method and are used to read or write input into output sequentially. Streams are a way to handle reading/writing files, network communications, or any kind of end-to-end information exchange in an efficient way.


Video Answer


2 Answers

Made streamtest for that purpose. It not only make streams tests cleaner but also allows to test V1 and V2 streams https://www.npmjs.com/package/streamtest

like image 80
nfroidure Avatar answered Oct 02 '22 07:10

nfroidure


I've also been using memorystream, but then putting my assertions into the finish event. That way it looks more like a real use of the stream being tested:

require('chai').should();  var fs = require('fs'); var path = require('path');  var MemoryStream = require('memorystream'); var memStream = MemoryStream.createWriteStream();  /**  * This is the Transform that we want to test:  */  var Parser = require('../lib/parser'); var parser = new Parser();  describe('Parser', function(){   it('something', function(done){     fs.createReadStream(path.join(__dirname, 'something.txt'))       .pipe(parser)       .pipe(memStream)       .on('finish', function() {          /**          * Check that our parser has created the right output:          */          memStream           .toString()           .should.eql('something');         done();       });   }); }); 

Checking objects can be done like this:

var memStream = MemoryStream.createWriteStream(null, {objectMode: true}); . . .       .on('finish', function() {         memStream           .queue[0]           .should.eql({ some: 'thing' });         done();       }); . . . 
like image 20
Mark Birbeck Avatar answered Oct 02 '22 08:10

Mark Birbeck