簡體   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