我正在尝试编写一个传递流错误的mocha测试,但如果流结束没有错误则会失败。
检测错误没有问题,但总是调用终结处理程序,即使流被强制错误输出也是如此。在此代码中,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();
})
})
一种似乎有点像黑客攻击的解决方法是将errored
变量放在处理程序之上,然后在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'));
}
});
全部要点here。
答案 0 :(得分:0)
修改的
我认为我们都同意这个问题的挑战在于正在执行多个Done()调用(两个事件触发)。如果Mocha看到多个完成的调用,则测试将自动失败。
看起来如果我们能够证明错误事件发生,我们的测试将是合理的。
Sinon是一个有用的图书馆,提供"间谍"告诉我们何时发出事件。
检查一下: 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.
});
});
};
它不是纯粹的原生解决方案,因为它依赖于Sinon。但是,我认为它仍然是一个很好的选择。
答案 1 :(得分:0)
更优雅的解决方案是从错误侦听器中删除完成侦听器。这类似于节点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);