2017-02-22 81 views
1

Допустим, что у меня есть этот простой код:Как заглушить https.request response.pipe с sinon.js?

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 test env - мокко, и может использовать chai слишком Пожалуйста, дайте мне несколько советов или примеров. Спасибо, Matt

ответ

2

Я завернул ваш код в функцию, которая принимает обратный вызов, потому что в текущей реализации мы фактически не знаем, когда трубопровод действительно закончен. Таким образом, предполагая, что мы имеем функцию, как это:

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

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

 
\t req.end(); 
 
};

Есть 3 проблемы решить:

  1. В ответ является читаемым поток. Мы хотим издеваться над данными, которые он испускает.
  2. Мы хотим, чтобы mock .pipe метод проверить, если мы трубопроводы в нужном потоке.
  3. Мы также должны издеваться https.request метод не делает фактический позвонить

Вот как мы можем достичь этого:

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

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

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

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

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

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

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

Позже вы могли бы сделать отдельные функции Например: createMockedStream. Или даже вытащить все эти препараты в отдельный метод и держать только утверждения в тесте.

 Смежные вопросы

  • Нет связанных вопросов^_^