简体   繁体   English

无极地吞下摩卡/柴断言

[英]Promise swallows mocha/chai assertion

I have a function in my project to send a bunch of emails one after the other. 我的项目中有一个功能,可以一个接一个地发送一堆电子邮件。 So, I compile these lists into an array of promises, and use Promise.all(...) to send them all and end the function after. 因此,我将这些列表编译成一个Promise.all(...)数组,并使用Promise.all(...)将它们全部发送出去,然后在此之后结束函数。 I am going to test this, however, and it seems as though Promise is 'swallowing' my error. 但是,我将对此进行测试,似乎Promise似乎正在“吞噬”我的错误。 Here is a snippet from my code: 这是我的代码片段:

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 in this case is just a standard callback that returns the error if there's an error, or null if not. 在这种情况nextnext只是一个标准回调,如果有错误,则返回错误,否则返回null。 In my test I have this code (which calls the previous snippet) 在我的测试中,我有以下代码(该代码称为上一个代码段)

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();
    });
});

What happens is if, say sentMail.length.should.be.eql(2); 例如,如果sentMail.length.should.be.eql(2);会发生什么? fails, then it will result in an UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: instead of being handled normally by mocha and failing the test. 失败,则将导致UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError:而不是被摩卡咖啡正常处理并导致测试失败。

How do I get Promise to not swallow this error and let mocha to handle it? 如何获得Promise不会吞下此错误并让Mocha处理该错误?

Here's the immediate problem you are facing. 这是您面临的直接问题。 The sequence of events is: 事件的顺序是:

  1. Promise.all(emailPromises) resolves, so it calls the success callback you passed to .then . Promise.all(emailPromises)解析,所以它要求你传递给成功回调.then

  2. next() is called. next()被调用。

  3. sentMail.length.should.be.eql(2); fails, which throws an exception. 失败,这将引发异常。

  4. Because the exception happened in a .then handler, it is assimilated to a promise rejection. 因为异常发生在.then处理程序中,所以它被等同于诺言拒绝。

From this point on, there's nothing which is able to handle the rejection. 从这一点开始,没有什么可以处理拒绝的。 You have this: 你有这个:

Promise.all(emailPromises).then(function() {
  next();
}, function(error) {
  next(error);
});

But you should note that when you call .then(success, failure) the failure handler will catch anything that happens before success is called. 但是您应该注意,当您调用.then(success, failure)failure处理程序将捕获调用success 之前发生的所有事情。 If success itself fails, then failure won't be called . 如果success本身失败了,那么failure 将不会被称为

As a minimal change you could rewrite it as: 作为最小的更改,您可以将其重写为:

Promise.all(emailPromises).then(function() {
  next();
}).catch(function(error) {
  next(error);
});

This would catch any errors that happen when next is called by the .then handler. 这将捕获.then处理程序调用next时发生的任何错误。

Ultimately, however, I would rewrite the whole thing so that it uses promises through and through. 但是,最终,我将重写整个内容,以便它始终使用promise。 Then you could just wait on the promise in your Mocha test and return that promise to Mocha. 然后,您可以等待Mocha测试中的承诺,然后将其返回给Mocha。 It would be much nicer overall. 总体来说会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM