如何使用sinon.js存根https.request response.pipe? [英] How to stub https.request response.pipe with sinon.js?

查看:80
本文介绍了如何使用sinon.js存根https.request response.pipe?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我有这个简单的代码:

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

var https = require('https');
var options = {
  host: 'openshift.redhat.com',
  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();

好吧,我对sinon.js有点陌生,我想问一下:如何对response.pipe()进行存根处理? 当然,我可以对https.request进行存根处理并使用.on和.end返回某物很简单,但是我不知道如何测试response.pipe()是否使用适当的参数...(nodejs文档)说响应是回调) 在这种情况下,文档编制无济于事! ofc testing env是摩卡咖啡,也可以使用chai 请给我一些建议或例子. 谢谢,马特

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

推荐答案

我将您的代码包装到一个接受回调的函数中,因为在当前实现中,我们实际上并不知道管道何时实际完成.因此,假设我们具有这样的功能:

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();
};

有3个问题需要解决:

  1. 响应是可读的流.我们要模拟它发出的数据.
  2. 我们要模拟.pipe方法来检查是否将管道传递到正确的流.
  3. 我们还需要模拟https.request方法而不进行实际调用

这是我们可以实现的方法:

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.com'}, (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);
		});
	});
});

稍后,您可以创建单独的功能,例如:createMockedStream.甚至将所有这些准备工作提取到单独的方法中,并仅在测试中保留断言.

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.

这篇关于如何使用sinon.js存根https.request response.pipe?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆