我的项目中有一个函数可以一个接一个地发送一堆电子邮件。所以,我将这些列表编译成一个promises数组,并使用Promise.all(...)
将它们全部发送出来并在之后结束该函数。不过,我打算对此进行测试,似乎Promise正在“吞咽”我的错误。以下是我的代码片段:
module.exports.checkForLoanEmailAndSendAll = function(next) {
// Some setup code
var emailPromises = [];
Object.keys(userLoanMap).forEach(function(user) {
emailPromises.push(new Promise((resolve, reject) => {
sendSingleLoanEmail(user, userLoanMap[user], loanEmailObj, function(error) {
if (error) {
reject(error);
} else {
resolve();
}
});
}));
});
Promise.all(emailPromises).then(function() {
next();
}, function(error) {
next(error);
});
}
在这种情况下, next
只是一个标准回调,如果有错误则返回错误,否则返回null。在我的测试中,我有这个代码(调用前面的代码片段)
it('sends loan emails to appropriate users if there is a email to send today', (done) => {
Emailer.checkForLoanEmailAndSendAll(function(error) {
should.not.exist(error);
var sentMail = nodemailerMock.mock.sentMail();
sentMail.length.should.be.eql(2);
// more should assertions
done();
});
});
如果sentMail.length.should.be.eql(2);
失败,那么会发生UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError:
,而不是通过mocha正常处理并且未通过测试。
如何让Promise不要吞下这个错误并让mocha来处理它?</ p>
答案 0 :(得分:0)
这是您面临的直接问题。事件的顺序是:
Promise.all(emailPromises)
结算,因此会调用您传递给.then
的成功回调。
next()
被调用。
sentMail.length.should.be.eql(2);
失败,会引发异常。
因为异常发生在.then
处理程序中,所以它被同意拒绝承诺。
从现在开始,没有什么能够处理拒绝。你有这个:
Promise.all(emailPromises).then(function() {
next();
}, function(error) {
next(error);
});
但是您应该注意,当您致电.then(success, failure)
时,failure
处理程序会捕获之前发生的任何事情 success
。如果success
本身失败,则failure
不会被称为。
作为最小的改变,您可以将其重写为:
Promise.all(emailPromises).then(function() {
next();
}).catch(function(error) {
next(error);
});
这将捕获next
处理程序调用{{1}}时发生的任何错误。
但是,最终,我会重写整个事情,以便它通过并通过承诺。然后你可以在Mocha测试中等待承诺并将这个承诺归还给Mocha。整体来说会好得多。