比方说,我有这个简单的代码:
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 有点陌生,我想问一下:如何 stub response.pipe()? 当然,我可以为 https.request 创建 stub 并使用 .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个问题需要解决:
- 因为响应是一个可读流。我们想模拟它发出的数据。
- 我们想模拟 .pipe 方法来检查我们是否正在通过管道传输到正确的流。
- 我们还需要模拟 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。或者甚至将所有这些准备工作提取到一个单独的方法中,并在测试中只保留断言。
关于javascript - 如何用 sinon.js stub https.request response.pipe?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42399877/