繁体   English   中英

Mocha如何知道异步测试中的测试失败?

[英]How does Mocha know about test failure in an asynchronous test?

我试图了解Mocha的异步代码( http://mochajs.org/#getting-started )是如何工作的。

describe('User', function() {
  describe('#save()', function() {
    it('should save without error', function(done) {
      var user = new User('Luna');
      user.save(function(err) {
        if (err) throw err;
        done();
      });
    });
  });
});

我想知道Mocha如何决定测试在幕后是成功还是失败。

我可以从上面的代码中理解,异步的user.save()会立即返回。 因此,在执行测试后,Mocha不会决定测试是成功还是失败it() user.save()最终成功调用done() ,那就是当Mocha认为它是一个成功的测试时。

我无法理解摩卡在上述情况下如何了解测试失败。 user.save()说, user.save()使用err参数集调用其回调,然后回调引发错误。 在这种情况下,没有调用Mocha的函数。 那么摩卡怎么会知道回调中发生了错误?

Mocha能够检测到阻止调用回调或返回promise的失败,因为它使用process.on('uncaughtException', ...); 检测未捕获的异常。 由于它以串行方式运行所有测试,因此它始终知道未捕获的异常属于哪个测试。 (有时人们对此感到困惑:告诉Mocha一个测试是异步的并不意味着Mocha将与其他测试并行运行。它只是告诉Mocha它应该等待回调或承诺。)

除非存在干预异常的内容,否则Mocha会知道测试失败并在检测到错误时立即报告错误。 这是一个例子。 由于抛出了一般异常,第一次测试失败。 由于expect检查失败,第二个失败。 它还引发了一个未处理的异常。

var chai = require("chai");
var expect = chai.expect;

it("failing test", function (done) {
    setTimeout(function () {
        throw new Error("pow!");
        done();
    }, 1000);
});

it("failing expect", function (done) {
    setTimeout(function () {
        expect(1).to.equal(2);
        done();
    }, 1000);
});

这是我的控制台上的输出:

  1) failing test
  2) failing expect

  0 passing (2s)
  2 failing

  1)  failing test:
     Uncaught Error: pow!
      at null._onTimeout (test.js:6:15)

  2)  failing expect:

      Uncaught AssertionError: expected 1 to equal 2
      + expected - actual

      -1
      +2

      at null._onTimeout (test.js:13:22)

堆栈跟踪指向正确的代码行。 如果异常发生得更深,那么堆栈会更充分。

当Mocha无法准确报告出错时,通常是因为有干预代码吞噬了引发的异常。 或者当你使用promises时,问题可能是有人忘了调用一个方法来指示是否应该完全处理promise,并且应该抛出未处理的异常。 (如何执行此操作取决于您使用的promise实现。)

它不会,这是一种耻辱。 它无法知道您的回调正在执行。 这是一种更简单的异步测试方法,您可以在完成时告诉测试。 正如您所注意到的,缺点是不会检测到异步回调中的错误。 没关系,Mocha挂钩到如路易斯所提到的process.on('uncaughtException',...) 请注意,如果您使用done而不是waitsFor并在jasmine中runs那么您将遇到问题

像js-test-driver这样的其他框架会强制你回调,所以测试框架可以try catch你的回调(并且你不需要调用done)。 您的测试将如下所示:

var AsynchronousTest = AsyncTestCase('User');

AsynchronousTest.prototype.testSave = function(queue) {
  queue.call('Saving user', function(callbacks) {
    var user = new User('Luna');
    user.save(callbacks.add(function(err) {
       if (err) throw err;
       // Run some asserts
    }));
  }); 
};

暂无
暂无

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

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