使用Mocha和Chai捕获超出范围的错误

时间:2014-11-03 17:05:15

标签: javascript node.js mocha chai

我正在修改node.js库以支持真正的异步操作。

我遇到了Mocha和Chai制作这个(类似的)测试通行证的麻烦。

it('should throw an error', function() {
    expect(function() {
        process.nextTick(function() {
            throw new Error('This is my error');
        });
    }).to.throw(Error);
});

问题是 - 由于nextTick - 错误被抛出it的范围,除了测试失败之外,Mocha还输出以下内容。

Uncaught Error: This is my error

构建此测试以使其成功的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

嗯......在一个成熟的应用程序中,我要做的就是使用像Sinon这样的东西来检查应该抛出错误的方法是否已被调用并且正在抛出。

在无法执行此操作的代码中,以下方法将捕获异常:

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

it('should throw an error', function(done) {
    var d = domain.create();
    d.on('error', function (err) {
        // Exit the current domain.
        d.exit();
        // We must execute this code at the next tick.
        process.nextTick(function () {
            console.log(err); // Just to show something on the console.
            expect(err instanceof Error).to.be.true;
            done();
        });
    });


    d.run(function () {
        process.nextTick(function() {
            throw new Error('This is my error');
        });
    });
});

此代码会在d中创建一个"domain"。域将在其中发生的未捕获异常上发出error个事件,因此我们在已创建的域(d.run(...))内运行测试并等待异常发生(d.on('error', ...) 。我们检查它是Error对象。 (在实际测试中,我还会检查错误消息。)当我们完成时,我们调用done()告诉Mocha异步测试结束。

error个事件的处理程序调用{​​{1}}。这样做是为了让Mocha能够正常捕获错误,如果断言(d.exit() ...)失败了。如果我们不退出域,则域将捕获错误。此外,检查本身必须在下一个刻度线上执行,以便在expect(err instanceof Error)域之外。

正在使用d问题吗?

否<!/强>

domain的文档附带一些关于在运行正在进行的进程(如服务器)时捕获未捕获的异常时关闭操作的警告。然后要做的是清洁可以清洁的东西并尽快退出。 但是,在测试中使用domain与Mocha已经在做的事情没有区别。 Mocha捕获异步代码中未处理的异常的方法是使用process.on('uncaughtException'。在捕获未处理的异常Mocha marks时,当前测试失败并继续。然而关于domain的{​​{3}}说“不要使用它,使用uncaughtException而不是。如果您使用它,请在每次未处理的异常后重新启动应用程序! “

Ergo,任何使用domains时遇到问题的人都不应该首先使用Mocha

答案 1 :(得分:0)

您正试图捕获错误函数的异常,该函数是抛出函数的容器。此外,因为函数包含在nextTick中,所以它在不同的堆栈中执行,因此无法捕获异常(不幸的是,这只是一个JS事件)。

请改为尝试:

it ('should throw an error', function (done) {

  process.nextTick(function () {
    var myFn = function () { throw new Error() };

    expect(myFn).to.throw(Error);

    // Tell mocha the test is complete 
    done();
  });
});

更新:没有正确的方法来构建此测试以使其通过,因为您无法在此方案中捕获异常。也许更新你的代码以使用回调来处理错误:

function doSomethingUnsafe() {

  try {
    // Run code here that may cause exceptions...
    callback(null, 'Woohoo! No errors!');
  } catch (e) {
    callback (e, null);
  }
}