How to spoof threads in NodeJS

I am trying to do unit testing of one of my node-js modules that is intensively running in threads. I am trying to simulate a stream (to which I will write) since in my module I have listeners ".on ('data / end)" which I would like to call. Essentially, I want to be able to do something like this:

var mockedStream = new require('stream').readable(); mockedStream.on('data', function withData('data') { console.dir(data); }); mockedStream.on('end', function() { console.dir('goodbye'); }); mockedStream.push('hello world'); mockedStream.close(); 

This executes, but the 'on' event never fires after I execute push (and .close () is invalid).

All the recommendations I can find regarding streams use the 'fs' or 'net' library as the basis for creating a new stream ( https://github.com/substack/stream-handbook ), or they mock it with sinon but the mockery becomes very long and very quick.

Is there a good way to provide a dummy thread like this?

+7
unit-testing node.js-stream
source share
3 answers

Instead of using Push, I had to use ".emit (<event>, <data>);"

My code layout now works and looks like this:

 var mockedStream = new require('stream').Readable(); mockedStream._read = function(size) { /* do nothing */ }; myModule.functionIWantToTest(mockedStream); // has .on() listeners in it mockedStream.emit('data', 'Hello data!'); mockedStream.emit('end'); 
+13
source share

To accept the answer is only partially correct. If all you need is events triggered using .emit('data', datum) , then everything is fine, but if you need to pass this dummy stream somewhere else, it will not work.

Mocking a readable stream is surprisingly easy, requiring only a readable library.

  let eventCount = 0; const mockEventStream = new Readable({ objectMode: true, read: function (size) { if (eventCount < 10) { eventCount = eventCount + 1; return this.push({message: 'event${eventCount}'}) } else { return this.push(null); } } }); 

Now you can direct this stream anywhere, and "data" and "end" will work.

Another example from a node document: https://nodejs.org/api/stream.html#stream_an_example_counting_stream

+5
source share

There is an easier way: stream.PassThrough

I just found that Node is very easy to skip the stream.PassThrough class, which I believe is what you are looking for.

From the node documents:

The stream.PassThrough class is a trivial implementation of a Transform stream that simply passes input bytes to the output. Its purpose is mainly for examples and testing ...

link to documents

The code from the question, modified:

 const { PassThrough } = require('stream'); const mockedStream = new PassThrough(); // <---- mockedStream.on('data', (d) => { console.dir(d); }); mockedStream.on('end', function() { console.dir('goodbye'); }); mockedStream.emit('data', 'hello world'); mockedStream.end(); // <-- end. not close. mockedStream.destroy(); 

mockedStream.push() also works, but like Buffer , so you might want to do: console.dir(d.toString());

+1
source share

All Articles