简体   繁体   English

如何在Promise.all()上测试catch块?

[英]How to test the catch block on Promise.all()?

Got this code: 得到这个代码:

//Waiting until all records are inserted to DB
Promise.all(promises).then(function(err){   
    context.succeed({ valid: true, succeedRecords:succeedRecords, failedRecords:failedRecords });
    //Log
    console.log("Lambda function is finished - Successfully added records: " + succeedRecords.length + ",  Failed records: " + 
        failedRecords.length + "  -  Total processed records: " + event.Records.length);   
})
.catch(function (err) {
    if (err) {
        var msg = "Got error from Promise.all(), Error: " + err;
        console.log(msg);
        context.fail({ valid: false, message: msg });
    }
});

I need to know how can I test the catch block using mocha ? 我需要知道如何使用mocha测试catch块?

Assume you just want to check if the Promise.all fails the code will be much simpler: 假设您只想检查Promise.all失败,代码将更简单:

//Waiting until all records are inserted to DB
return Promise.all(promises).then(function(err){   
  context.succeed({ valid: true, succeedRecords:succeedRecords, failedRecords:failedRecords });
  //Log
  console.log("Lambda function is finished - Successfully added records: " + succeedRecords.length + ",  Failed records: " + 
    failedRecords.length + "  -  Total processed records: " + event.Records.length);   
});

mocha in this case will append a catch to the returned promise and fail if called. 在这种情况下, mocha会将一个catch附加到返回的promise,如果调用则会失败。

In some contexts you want to handle the error scenario, perform some checks and fail only in specific scenarios: 在某些情况下,您希望处理错误情形,执行某些检查并仅在特定情况下失败:

//Waiting until all records are inserted to DB
return Promise.all(promises).then(function(err){   
  context.succeed({ valid: true, succeedRecords:succeedRecords, failedRecords:failedRecords });
  //Log
  console.log("Lambda function is finished - Successfully added records: " + succeedRecords.length + ",  Failed records: " + 
    failedRecords.length + "  -  Total processed records: " + event.Records.length);   
})
.catch(function (err) {
  var msg = "Got error from Promise.all(), Error: " + err;
  console.log(msg);
  // ... do some stuff here
  context.fail({ valid: false, message: msg });

  // add an expectation here to check if the error message is correct
  // If the error message is "this error" the test passes, otherwise it will fail
  expect(err).to.be.eql('this error');
});

In detail 详细

I'll take a step back here and try to explain in detail how it works. 我会在这里退一步,试着详细解释它是如何工作的。 Say you have a test with a Promise that rejects: 假设你有一个拒绝承诺的测试:

// your code
it('rejects', () => {

  return Promise.reject();

});

This test will fail as mocha will do the following (the actual code is here ): 此测试将失败,因为mocha将执行以下操作(实际代码在此处 ):

// this is pseudo code for the mocha insides
var result = fn.call(ctx);
if (result && result.then) {

  result
    .then(function successCase() {
      // all fine here
      done();
    })
    .catch(function errorCase(reason) {
      done(reason);
    });
  }

So the promise you return will be chained with a .then and a .catch and two callbacks will be passed: one for success (make the test pass) and one for error (make the test fail). 因此,您返回的承诺将使用.catch.catch链接.then并且将传递两个回调:一个用于成功(使测试通过),一个用于错误(使测试失败)。

In your rejection case above what happens is the following: 在您的拒绝案例中,会发生以下情况:

  // mocha code (I've just replaced the function call with its result)
  var result = Promise.reject();
  if(result && result.then){
    result.then(function successCase() {
      // this is not called!
      done();
    })
    .catch(function errorCase(reason) {
      // it will land here!
      done(reason);
    } );
  }

In the code of the OP question, the Promise may error and that error will be trapped: 在OP问题的代码中,Promise可能会出错并且该错误将被捕获:

Promise.reject()
  .catch( function( err ){
    var msg = "Got error from Promise.all(), Error: " + err;
    console.log(msg);
    context.fail({ valid: false, message: msg });
  }); <-- what is the output here?

The above is the case where your Promise.all rejects and you catch it within the test. 以上是您的Promise.all拒绝并且您在测试中捕获它的情况。 The result of that catch is... success! catch的结果是......成功!

// your code
Promise.reject()
  .catch( function( err ){
    var msg = "Got error from Promise.all(), Error: " + err;
    console.log(msg);
    context.fail({ valid: false, message: msg });
  })

  // mocha code
  .then(function successCase() {
    // this is called! (and make the test pass)
    done();
  })
  .catch(function errorCase(reason) {
    // it will NOT call this
    done(reason);
  });

Now, say you WANT the Promise to reject, catch the error and then test something (maybe the error message? some other option? etc...). 现在,假设您想要拒绝承诺,捕获错误然后测试一些东西(可能是错误消息?其他选项?等等......)。 How do you do it given that the code above? 鉴于上面的代码你怎么做? Easy, you throw an error in some way. 很容易,你以某种方式抛出错误。 One way could be to explicitly throw the error or you can use an assertion (an assertion that fails will throw an error). 一种方法可能是显式抛出错误,或者您可以使用断言(失败的断言将引发错误)。

// your code
Promise.reject()
  .catch( function( err ){
    var msg = "Got error from Promise.all(), Error: " + err;
    console.log(msg);
    context.fail({ valid: false, message: msg });

    // It will throw!
    expect(true).to.be(false);

    // or you can go vanilla
    throw Error("I don't like Errors!");
  })

  // mocha code
  .then(function successCase() {
    // this is NOT called!
    done();
  })
  .catch(function errorCase(reason) {
    // it will call this! (and make the test fail)
    done(reason);
  });

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

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