Make mocha tests show the actual error

穿精又带淫゛_ 提交于 2019-11-27 08:24:29

问题


One of the things that I find frustrating about Mocha is that when tests fail, they don't give the actual error message of the failing line, Instead, they just end with Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

Take this test for example:

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();
        });
    });
});

The output is:

  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.

The assert.isFalse is failing, but the message that should be displayed ("result has an error") isn't displayed. In fact, processing seems to stop right there because done() is never called. Take that line out and the test passes because done() is called.

So, what am I missing? Why do Mocha tests behave this way? The actual test library I'm using is:

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

Does anyone know what I'm doing wrong or why this behaves this way?


回答1:


It looks like your API is using promises. Before trying anything else, I would suggest checking what the documentation of the API says about promises and how to deal with unhandled exceptions because this may be what is happening here. Some promise implementations require that you call .done() at the end of your call chain to ensure that uncaught exceptions are going to be processed. Some require that some global promise setting be properly configured. The Bluebird documentation gives a good discussion of the issues.

Mocha is capable of handling uncaught exceptions in run-of-the-mill code:

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);
    });
});

This will result in the output:

  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)



回答2:


I've encountered the same in my code, using Q for promises.

What happened was:

  • The assertion inside the then block failed.
  • The rest of the then block, including the done() statement, was not executed.
  • Q went looking for a catch block, which wasn't there.
  • This led to a 'hanging' promise, and thus to a Mocha 2000 ms timeout.

I worked around it by doing something like this:

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);
        });
    });
});


来源:https://stackoverflow.com/questions/32648902/make-mocha-tests-show-the-actual-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!