Nodeunit没有检测到done()

试图加快node.js和nodeunit的速度,但是在nodeunit中发现一个问题,在其中一个testing中没有看到对test.done()的调用。

代码:

 // Added for clarity. var client = require("restify").createJsonClient({ "version": "*", "url": "http://localhost:" + server.Port }); exports["tests"] = { "setUp": function (callback) { server.StartServer(); callback(); }, "tearDown": function (callback) { callback(); }, "CanIHaveSomeTeaPlease?": function (test) { test.expect(4); client.get("/tea", function (err, req, res, data) { test.equal(err.statusCode, 418, "Expected ImATeapot Error."); test.equal(err.message, "Want a biscuit?", "Expected to be asked if I want a buscuit."); test.equal(err.restCode, "ImATeapotError"); test.equal(err.name, "ImATeapotError"); test.done(); }); }, // Note: I expect this test to fail as it is a copy of the above // test on a different url that doesn't return the ImATeapot // HTTP error. But it doesn't look like it's detecting it // properly. "TakeThisInfo": function (test) { test.expect(4); client.put("/push", { "hello": "world" }, function (err, req, res, data) { test.equal(err.statusCode, 418, "Expected ImATeapot Error."); test.equal(err.message, "Want a biscuit?", "Expected to be asked if I want a buscuit."); test.equal(err.restCode, "ImATeapotError"); test.equal(err.name, "ImATeapotError"); test.done(); }); } }; 

输出:

 FAILURES: Undone tests (or their setups/teardowns): - tests - TakeThisInfo To fix this, make sure all tests call test.done() 

我希望这是愚蠢的。

版本: –

 Node: 0.10.21 NPM: 1.3.11 Nodeunit: 0.8.2 Grunt-CLI: 0.1.10 Grunt: 0.4.1 

首先,我不知道你的代码中有什么“服务器”,但是我希望它是asynchronous的,所以在你的setUp函数中有更多的东西:

 function (callback) { server.StartServer(function(){ callback(); }); } 

其次,继续介绍nodeunit 在EVERYtesting之前和之后执行startUp和tearDown函数,所以我怀疑你正在启动你的服务器2次(就像你没有真正closures它)。

我已经花了最近几个小时解决了这个问题,现在已经清楚的是,nodeunit没有能力捕获和显示由IO或setTimeouttypes进程触发的函数中抛出的exception。 考虑到JavaScript的运行方式,这并不奇怪。 一旦你确定没有任何exception,一切都可以正常工作,但是如果你的代码有错误,你将会得到“未经testing”的信息。 下面是我解决我的问题(使用restify路线作为例子):

 function myRoute(req, res, next) { try { // your code goes here... } catch (err) { // write it to the console (for unit testing) console.log(err); // pass the error to the next function. next(err); } } 

一旦我以这种方式了解问题,修复它,因为更清晰,我能够通过我所有的testing!

我怀疑你实际上没有在第二个testing中调用test.done() 。 在那里放一个console.log()调用来validation你实际上正在进行这个调用。

FWIW,我在下面用你的testing的简化版本重申了所描述的问题。 如果省略了on('error', function() {...})处理程序,则第二个testing无法完成。 因此,我的理论是,你的/push端点在restify模块中触发了一个不同的行为。 也就是说,你确定 restify是在那里用一个err属性来调用你的callback,还是在做一些不同的事情? 例如,像下面这样http.get一个像http.get这样的事件。

 var http = require('http'); exports.test1 = function (test) { test.expect(1); http.get({hostname: "www.broofa.com", path: "/"}, function (res) { test.equal(res.statusCode, 200, 'got 200'); test.done(); }); }; exports.test2 = function (test) { test.expect(1); http.get({hostname: "www.no-such-domain.com", path: "/"}, function (res) { test.equal(res.statusCode, 200, 'got 200'); test.done(); }).on('error', function() { // Comment line below out to repro the "Undone tests" error test.done(); }); }; 

我正在通过将服务器分入安装过程中的自己的进程来解决这个问题,然后在拆解中将其终止。 认为这个问题是关于正在创build的服务器,而不是关机。 感谢@matteofigus的。

 var cp = null; // child process exports["tests"] = { "setUp": function (callback) { cp = fork("./lib/server.js", {"silent": true}); callback(); }, "tearDown": function (callback) { cp.kill("SIGHUP"); callback(); }, "CanIHaveSomeTeaPlease?": function (test) { test.expect(4); client.get("/tea", function (err, req, res, data) { test.equal(err.statusCode, 418, "Expected ImATeapot Error."); test.equal(err.message, "Want a biscuit?", "Expected to be asked if I want a buscuit."); test.equal(err.restCode, "ImATeapotError"); test.equal(err.name, "ImATeapotError"); test.done(); }); }, "TakeThisInfo": function (test) { test.expect(1); client.put("/push", { "hello": "world" }, function (err, req, res, data) { test.ok(false); test.done(); }); } };