承诺吞下摩卡/柴主张

时间:2017-03-06 17:28:41

标签: javascript node.js mocha chai es6-promise

我的项目中有一个函数可以一个接一个地发送一堆电子邮件。所以,我将这些列表编译成一个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>

1 个答案:

答案 0 :(得分:0)

这是您面临的直接问题。事件的顺序是:

  1. Promise.all(emailPromises)结算,因此会调用您传递给.then的成功回调。

  2. next()被调用。

  3. sentMail.length.should.be.eql(2);失败,会引发异常。

  4. 因为异常发生在.then处理程序中,所以它被同意拒绝承诺。

  5. 从现在开始,没有什么能够处理拒绝。你有这个:

    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。整体来说会好得多。