赶上摩卡和柴的超出范围的错误

我正在修改一个node.js库来支持真正的asynchronous操作。

我和摩卡和柴一起做了这个类似的testing。

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

问题是 – 由于nextTick – 错误被抛出它的范围,除了testing失败,摩卡也输出下面。

 Uncaught Error: This is my error 

构build这个testing的正确方法是什么?

嗯…在一个完整的应用程序,我会做的可能是使用像Sinon这样的东西来检查应该抛出一个错误的方法已经被调用并正在抛出。

在代码中你不能这样做,那么下面的方法将陷阱exception:

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

这段代码创build一个存储在d的“域” 。 一个域将发生error事件发生在其中的未捕获exception,所以我们在我们创build的域( d.run(...) )内运行testing,并等待发生exception( d.on('error', ... )。我们检查它是一个Error对象(在一个真正的testing中,我也会检查错误信息)。当我们完成时,我们调用done()来告诉Mochaasynchronoustesting已经结束。

error事件处理程序调用d.exit() 。 这是为了让摩卡能够正常地捕捉到错误,如果断言( expect(err instanceof Error) …)失败。 如果我们不退出域名,那么域名将会陷入错误。 此外,检查本身必须在下一个时间点上执行,以在d域之外。

使用domain A的问题?

没有!

在运行正在进行的过程(如服务器)时,一旦捕获到未捕获的exception, domain的文档就会附带一些关于closures操作的警告。 那么要做的就是清理干净的东西,尽快退出。 然而,在testing中使用domain与摩卡已经做的没有什么不同。 Mocha在asynchronous代码中捕获未处理的exception的方式是使用process.on('uncaughtException' 。捕获一个未处理的exception时,Mocha将当前的testing标记为失败并继续执行 ,但关于uncaughtException的文档说“不要使用它, 相反 ,如果你使用它,在每个未处理的exception之后重新启动你的应用程序!“

Ergo, 任何使用domain都不应该首先使用Mocha

你正在试图捕捉不正确的函数的exception,抛出函数的容器。 另外,因为函数被封装在nextTick中,所以它在不同的堆栈中执行,因此不能捕获exception(不幸的是,这只是一个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(); }); }); 

更新:没有正确的方法来构build此testing,以使其通过,因为在此scheme中无法捕获exception。 也许更新你的代码来使用callback来处理错误:

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