如何使用 sinon.js 存根 https.request response.pipe?

2023-12-19

假设我有这个简单的代码:

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测试环境是mocha,也可以使用chai 请给我一些建议或例子。 谢谢,马特


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

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 方法而不进行实际调用

以下是我们如何实现这一目标:

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。或者甚至将所有这些准备工作提取到一个单独的方法中,并在测试中仅保留断言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 sinon.js 存根 https.request response.pipe? 的相关文章

随机推荐