我想对一个函数进行单元测试。 在那个函数中,我使用Co和生成器函数。 当发生错误时我抓住它,然后用错误
调用cb在我的单元测试中,我做了一个错误的断言,但摩卡没有报告它,它只是超时:
//function to test
function start(data, cb) {
co(function * coStart() {
yield Promise.reject('err'); // yield error for sake of demo
}).then(function(result){
return cb(null, result);
}).catch(function (err) {
// we get here
return cb(err);
});
}
// mocha test
it('fails on incorrect data', function(done){
MyModel.start({'foo': 'bar'}, function(err, res){
assert.equal(err, 'err2'); //this fails but mocha just stops here and times out
done();
});
});
显然我在这里做错了什么?
我知道你可以在测试中返回对mocha的承诺并省略完成回调,但我的函数'start'不能返回一个promise,它就像中间件一样,所以它应该与回调一起工作
答案 0 :(得分:1)
您的代码与此类似:
Promise.reject('err')
.catch(() => {
// throw another exception
throw 'foo';
});
即:在.catch()
子句中,抛出另一个异常(在您的情况下,由assert.equal(err, 'err2')
引发的异常),同步,未被处理(例如,另一个.catch()
子句)。这将导致忽略第二个异常(请参阅this answer以获得解释),但它将阻止测试用例完成(从未到达done()
行,从而超时测试用例)。
如果你真的需要回调支持,你可以通过在.catch()
中添加另一个start()
子句,或者通过异步调用回调来解决这个问题:
return setImmediate(function() { cb(null, result) });
...
return setImmediate(function() { cb(err) });
...
但理想情况下,您应该考虑完全删除回调支持的可能性,并且只是绕过承诺。 Mocha支持开箱即用的承诺,因此代码看起来像这样:
function start(data) {
return co(function * coStart() {
yield Promise.reject('err');
});
}
it('fails on incorrect data', function(){
return start({'foo': 'bar'}).then(function() {
throw new Error('should not be reached');
}, function(err) {
assert.equal(err, 'err2');
});
});