Unit testing 让摩卡测试显示实际错误

Unit testing 让摩卡测试显示实际错误,unit-testing,mocha.js,chai,Unit Testing,Mocha.js,Chai,我对Mocha感到沮丧的一件事是,当测试失败时,它们不会给出失败线路的实际错误消息,相反,它们只是以错误结束:超过2000ms的超时。确保在此测试中调用了done()回调。 以这个测试为例: describe("myTest", function() { it("should return valid JSON.", function(done) { api.myCall("valid value").then(function(result) {

我对Mocha感到沮丧的一件事是,当测试失败时,它们不会给出失败线路的实际错误消息,相反,它们只是以错误结束:超过2000ms的超时。确保在此测试中调用了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.
assert.isFalse失败,但未显示应显示的消息(“结果有错误”)。事实上,处理似乎就此停止,因为从未调用过done()。去掉这一行,测试就通过了,因为调用了done()

那么,我错过了什么?为什么摩卡咖啡测试会这样?我使用的实际测试库是:

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

有人知道我做错了什么,或者为什么会这样吗?

您的API似乎在使用承诺。在尝试其他方法之前,我建议检查API文档中关于承诺的内容,以及如何处理未处理的异常,因为这里可能正在发生这种情况。一些promise实现要求您在调用链的末尾调用
.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)
foo
1) 让摩卡抓住这个例外
0通过(1s)
1失败
1) foo让摩卡捕获异常:
未捕获的断言错误:foo:应为true,否则为false
一声令下。(/tmp/t7/node_modules/chai/lib/chai/core/assertions.js:286:10)
在Assertion.Object.defineProperty.get(/tmp/t7/node_modules/chai/lib/chai/utils/addProperty.js:35:29)
在Function.assert.isFalse(/tmp/t7/node_modules/chai/lib/chai/interface/assert.js:297:31)
在空时超时(/tmp/t7/test.js:8:20)
在Timer.listOnTimeout(timers.js:119:15)

看起来您的API正在使用承诺。在尝试其他方法之前,我建议检查API文档中关于承诺的内容,以及如何处理未处理的异常,因为这里可能正在发生这种情况。一些promise实现要求您在调用链的末尾调用
.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)
foo
1) 让摩卡抓住这个例外
0通过(1s)
1失败
1) foo让摩卡捕获异常:
未捕获的断言错误:foo:应为true,否则为false
一声令下。(/tmp/t7/node_modules/chai/lib/chai/core/assertions.js:286:10)
在Assertion.Object.defineProperty.get(/tmp/t7/node_modules/chai/lib/chai/utils/addProperty.js:35:29)
在Function.assert.isFalse(/tmp/t7/node_modules/chai/lib/chai/interface/assert.js:297:31)
在空时超时(/tmp/t7/test.js:8:20)
在Timer.listOnTimeout(timers.js:119:15)

我在代码中也遇到了同样的问题,使用
Q
表示承诺

发生的情况是:

  • then
    块内的断言失败
  • 未执行
    then
    块的其余部分,包括
    done()
    语句
  • Q去寻找一个
    catch
    块,它不在那里
  • 这导致了一个“悬而未决”的承诺,从而导致了摩卡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);
        });
    });
});

我在代码中也遇到了同样的问题,使用
Q
表示承诺

发生的情况是:

  • then
    块内的断言失败
  • 未执行
    then
    块的其余部分,包括
    done()
    语句
  • Q去寻找一个
    catch
    块,它不在那里
  • 这导致了一个“悬而未决”的承诺,从而导致了摩卡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);
        });
    });
});