Mocha,应该 - 在测试具有承诺的异步函数时,断言错误是静默的

时间:2016-11-15 13:38:42

标签: javascript asynchronous promise mocha chai

我有一个困扰我的小问题.. 下面的代码显示了一个异步测试,在该测试中我们测试了一个我们无法控制的代码(测试的黑盒子,我可以改变它)。

黑盒代码在完成后调度事件,测试侦听此事件并断言数据。

问题是当存在断言错误时,由promise错误处理程序而不是测试框架引发异常,因此完成函数永远不会执行,并且我们会在此测试中获得超时错误。

通过试用和解决方案很容易解决它赶上it()区块,但总是尝试&捕获it()块内?到目前为止,我信任测试框架来处理异常

另一个问题是,错误是沉默的,除非catch打印它,并且因为它的blackbox我们不能指望它。

这里的提示帮助我解决了,但我不喜欢这些解决方案: https://github.com/mochajs/mocha/issues/1128#issuecomment-40866763

它与其他类似问题不同,因为在it()块中我们没有对promise对象的任何引用。

describe.only("test", function () {

  var event;

  // blackbox simulates a code we have no controler over
  // inside this code we have a promise, when this promise resolves it triggers event
  var blackbox = function () {
    var promise = new Promise(function (resolve, reject) {
      resolve();
    });

    promise.then(function () {
      event(4);
    }).catch(function (e) {
      console.log(e);
    });
  };

  it("async with blackbox promise", function (done) {
    // this simulates event listenner, when the event is triggered the code executes
    event = function (data) {
      // this assertion works and everything is fine
      data.should.be.equal(4);
      // this assertion thrown exception that is being cought by the promise reject handler and
      // isnt cought by the testing framework (chai / mocha)
      data.should.be.equal(5);
      // because the exception is thrown we never reach the done
      done();
    };

    blackbox();

  });
});

1 个答案:

答案 0 :(得分:1)

你在mocha中测试承诺的方式是你返回它们并让它完成决定何时失败的工作。

因此,第一步是在blackbox函数中提供承诺:

// blackbox simulates a code we have no controler over
// inside this code we have a promise, when this promise resolves it triggers event
var blackbox = function () {
  var promise = new Promise(function (resolve, reject) {
    resolve();
  });

  return promise.then(function () {
    event(4);
  });
  // do not catch here unless you want the test to not fail on error
};

现在让我们更改测试代码以处理承诺:

it("async with blackbox promise", function () {
  // this simulates event listenner, when the event is triggered the code executes
  event = function (data) {
    // this assertion works and everything is fine
    data.should.be.equal(4);
    // this assertion thrown exception that is being cought by the promise reject handler
    data.should.be.equal(5);
  };
  // mocha will append a rejection handler to this promise here and fail if it gets called
  return blackbox();

});