admin管理员组

文章数量:1278789

Let's say, that I have this simple code:

var https = require('https');
var options = {
  host: 'openshift.redhat',
  port: 443,
  path: '/broker/rest/api',
  method: 'GET'
};
var req = https.request(options, function(response) {
  console.log(response.statusCode);
  response.pipe(save stream to file with fs)
});
req.on('error', function(e) {
  console.error(e);
});
req.end();

Well, I'm bit new with sinon.js and I'd like to ask: How to stub response.pipe()? Of course, I can make stub for https.request and return somethin with .on and .end and thats easy, but I have no idea, how to test if response.pipe() was called with proper arguments... (nodejs documentation says that response is callback) Documentation is not helpful in this case! ofc testing env is mocha, and can use chai too Please give me some advices or examples. Thanks, Matt

Let's say, that I have this simple code:

var https = require('https');
var options = {
  host: 'openshift.redhat.',
  port: 443,
  path: '/broker/rest/api',
  method: 'GET'
};
var req = https.request(options, function(response) {
  console.log(response.statusCode);
  response.pipe(save stream to file with fs)
});
req.on('error', function(e) {
  console.error(e);
});
req.end();

Well, I'm bit new with sinon.js and I'd like to ask: How to stub response.pipe()? Of course, I can make stub for https.request and return somethin with .on and .end and thats easy, but I have no idea, how to test if response.pipe() was called with proper arguments... (nodejs documentation says that response is callback) Documentation is not helpful in this case! ofc testing env is mocha, and can use chai too Please give me some advices or examples. Thanks, Matt

Share Improve this question edited Feb 22, 2017 at 19:04 Arogancky asked Feb 22, 2017 at 18:51 AroganckyArogancky 1132 silver badges7 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 6

I wrapped your code into a function that accepts a callback because in current implementation we don't actually know when the piping is actually finished. So assuming we have a function like this:

const downloadToFile = function (options, callback) {
	let req = https.request(options, function (err, stream) {
		let writeStream = fs.createWriteStream('./output.json');
		stream.pipe(writeStream);

		//Notify that the content was successfully writtent into a file
		stream.on('end', () => callback(null));
		//Notify the caller that error happened.
		stream.on('error', err => callback(err));
	});

	req.end();
};

There are 3 problems to solve:

  1. As response is a readable stream. We want to mock the data it emits.
  2. We want to mock .pipe method check if we are piping to the right stream.
  3. We also need to mock https.request method not to make actual call

Here is how we can achieve this:

const {PassThrough} = require('stream');

describe('#downloadToFile', () => {
	it('should save the data to output.json', function (callback) {
		const mockResponse = `{"data": 123}`;
		//Using a built-in PassThrough stream to emit needed data.
		const mockStream = new PassThrough();
		mockStream.push(mockResponse);
		mockStream.end(); //Mark that we pushed all the data.

		//Patch the 'https' module not to make an actual call
		//but to return our stream instead
		sinon.stub(https, 'request', function (options, callback) {
			callback(null, mockStream);

			return {end: sinon.stub()}; //Stub end method btw
		});

		//Finally keep track of how 'pipe' is going to be called
		sinon.spy(mockStream, 'pipe');

		downloadToFile({url: 'http://google.'}, (err) => {
			//Here you have the full control over what's happened
			sinon.assert.calledOnce(mockStream.pipe);
			//We can get the stream that we piped to.
			let writable = mockStream.pipe.getCall(0).args[0];
			assert.equal(writable.path, './output.json');

			//Tell mocha that the test is finished. Pass an error if any.
			callback(err);
		});
	});
});

Later you could make separate functions like: createMockedStream. Or even extract all these preparations into a separate method and keep only asserts in a test.

From Sinon documentation, this has been removed from v3.0.0:

var stub = sinon.stub(object, "method", func);`

Instead you should use:

stub(obj, 'meth').callsFake(fn)

本文标签: javascriptHow to stub httpsrequest responsepipe with sinonjsStack Overflow