javascript - 如何测试 Promise.all() 上的 catch block ?

标签 javascript unit-testing promise mocha.js chai

得到这个代码:

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

我需要知道如何使用 mocha 测试 catch block ?

最佳答案

假设您只想检查 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 会将 catch 附加到返回的 Promise 中,如果调用则失败。

在某些情况下,您希望处理错误场景,执行一些检查并仅在特定场景下失败:

//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');
});

详细

我将退一步并尝试详细解释它是如何工作的。 假设您有一个 Promise 被拒绝的测试:

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

  return Promise.reject();

});

此测试将失败,因为 mocha 将执行以下操作(实际代码为 here ):

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

因此,您返回的 Promise 将与 .then.catch 链接起来,并且将传递两个回调:一个用于成功(使测试通过),另一个用于一个表示错误(使测试失败)。

在上述拒绝案例中,发生的情况如下:

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

在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?

以上是您的 Promise.all 被拒绝并且您在测试中捕获它的情况。 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);
  });

现在,假设您希望 Promise 拒绝,捕获错误,然后测试某些内容(也许是错误消息?其他选项?等等...)。鉴于上面的代码,你如何做到这一点?很简单,你以某种方式抛出错误。一种方法可能是显式引发错误,或者您可以使用断言(失败的断言将引发错误)。

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

关于javascript - 如何测试 Promise.all() 上的 catch block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40881623/

相关文章:

javascript - 如何根据数据属性对父div中的子div进行排序?

javascript - 单元测试事件驱动的javascript

javascript - 不使用 <any> 的 typescript 和解决 promise

Javascript promise .catch仍然调用final变量.then

javascript - 状态解构仅适用于箭头函数类方法?

javascript - 向 Promise.all() 添加一个 Promise

unit-testing - 单元测试 反模式目录

python - 仅当测试通过时才在 git 中提交

javascript - Node、MongoDB 和 Promise 的问题

javascript - 如何通过离开页面处理客户端断开的socket.io?