testing应该通过stream错误,失败的成功

我试图写一个摩卡testing传递stream错误,但如果stream没有错误结束失败。

检测错误是没有问题的,但总是调用完成处理程序,即使stream被强制错误。 在这段代码中, error处理程序的should.exist(err)断言可以正常工作,但是finish处理程序仍会抛出错误。

 describe('catch stream errors', function() { it('should throw an error', function(done) { var stream = failStream(); stream.on('error', function(err) { should.exist(err); done(); }) stream.on('finish', function() { done(new Error('Why does this still run?')); }); stream.write(); stream.end(); }) }) 

一种解决方法,看起来有点像黑客攻击,就是把一个erroredvariables放在处理程序的上面,然后把它翻到error处理程序中,并检查finish处理程序中的值。 似乎应该有一个更好的方式来处理这个问题。

 var errored = false; stream.on('error', function(err) { should.exist(err); errored = true; done(); }) stream.on('finish', function() { if (!errored) { done(new Error('Error suppressed')); } }); 

充分的要点在这里 。

更优雅的解决scheme是从错误侦听器中删除完成侦听器。 这与节点的lib/stream源文件中的cleanup方法类似。

 // Refactor out the listeners var onerror = function(err) { should.exist(err); this.removeListener('finish', onfinish); done(); }; var onfinish = function() { done(new Error('Expected stream to throw an error.')); }; stream.on('error', onerror); stream.on('finish', onfinish); 

编辑

我认为我们都同意这个问题的挑战是多个Done()调用正在执行(两个事件触发)。 如果摩卡看到多个完成的呼叫,testing将自动失败。

看起来如果我们能certificate错误事件发生,我们的testing将是合理的。

Sinon是一个有用的libray,提供“间谍”,告诉我们什么时候发生事件。

看看这个: https : //github.com/mochajs/mocha/wiki/Spies

 var stream = require('stream'); var util = require('util'); var should = require('should'); // Writer util.inherits(Writer, stream.Writable); function Writer(opt) { stream.Writable.call(this, opt); } Writer.prototype._write = function(data, encoding, callback) { console.log(data.toString()); // This will cause the stream to always return error callback(new Error('FAIL STREAM')); }; var test = module.exports.run = function() { describe('catch stream errors', function() { it('should throw an error', function() { // setup the stream that always fails var stream = new Writer(); // Initialize the spies var errorSpy = sinon.spy(); var finishSpy = sinon.spy(); // When the stream events fire, // callback the respective spies stream.on('error', errorSpy); stream.on('finish', finishSpy); // Write to the stream, I setup the stream to // always return an error when something is written. stream.write('hello'); stream.end(); console.log('errorSpy Called: '+ errorSpy.called); console.log('finishSpy Called: '+ finishSpy.called); errorSpy.called.should.equal(true); // Mocha Test Fails If Error Event Was Not Emitted. finishSpy.called.should.equal(true); // Mocha Test Fails If Finish Never Happened. }); }); }; 

它不是一个纯粹的本地解决scheme,因为它依赖于Sinon。 不过,我认为它仍然是一个很好的select。