使摩卡测试显示实际误差



Mocha让我感到沮丧的一件事是,当测试失败时,它们不会给出失败行的实际错误消息,而是以 error: timeout of 2000ms exceeded结束。确保done()回调在这个测试中被调用。

以下面的测试为例:

describe("myTest", function() {
    it("should return valid JSON.", function(done) {
        api.myCall("valid value").then(function(result) {
            console.log(result);
            var resultObj = JSON.parse(result);
            assert.isFalse(resultObj.hasOwnProperty("error"), "result has an error");
            done();
        });
    });
});

输出为:

  myTest
{"error":null,"status":403}
    1) should return valid JSON.

  0 passing (2s)
  1 failing
  1) myTest should return valid JSON.:
     Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

断言。isFalse失败了,但是应该显示的消息("结果有错误")没有显示。实际上,处理似乎就在那里停止了,因为从未调用done()。把这行去掉,测试通过了,因为done()被调用了。

那么,我错过了什么?为什么Mocha测试是这样的?我使用的实际测试库是:

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

有没有人知道我做错了什么,或者为什么这个行为是这样的?

看起来你的API正在使用promise。在尝试其他任何事情之前,我建议检查API的文档中关于承诺的说明以及如何处理未处理的异常,因为这可能就是这里发生的事情。一些承诺实现要求您在调用链的末尾调用.done(),以确保未捕获的异常将被处理。有些要求正确配置一些全局承诺设置。Bluebird文档对这些问题进行了很好的讨论。

Mocha能够处理普通代码中未捕获的异常:

var chai = require("chai");
var assert = chai.assert;
chai.config.includeStack = true;
describe("foo", function() {
    it("let the exception be caught by Mocha", function(done) {
        setTimeout(function () {
            assert.isFalse(true, "foo");
            done();
        }, 1000);
    });
});

这将导致输出:

  foo
    1) let the exception be caught by Mocha

  0 passing (1s)
  1 failing
  1) foo let the exception be caught by Mocha:
     Uncaught AssertionError: foo: expected true to be false
      at Assertion.<anonymous> (/tmp/t7/node_modules/chai/lib/chai/core/assertions.js:286:10)
      at Assertion.Object.defineProperty.get (/tmp/t7/node_modules/chai/lib/chai/utils/addProperty.js:35:29)
      at Function.assert.isFalse (/tmp/t7/node_modules/chai/lib/chai/interface/assert.js:297:31)
      at null._onTimeout (/tmp/t7/test.js:8:20)
      at Timer.listOnTimeout (timers.js:119:15)

我在我的代码中遇到过同样的情况,使用Q来表示承诺。

结果是:

  • then块内断言失败。
  • then块的其余部分,包括done()语句,没有执行。
  • Q去寻找一个catch块,它不存在。
  • 这会导致'hang ' promise,从而导致Mocha 2000毫秒超时。

我通过这样做来解决这个问题:

describe("myTest", function() {
    it("should return valid JSON.", function(done) {
        api.myCall("valid value").then(function(result) {
            console.log(result);
            var resultObj = JSON.parse(result);
            assert.isFalse(resultObj.hasOwnProperty("error"), "result has an error");
            done();
        })
        .catch(function(err) {
            console.error(err);
            done(err);
        });
    });
});

最新更新