Nodeunit не обнаруживает сделано ()
Пытаюсь набрать скорость с помощью node.js и nodeunit, но я обнаружил проблему с nodeunit, когда он не видит вызов 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
4 ответа
Во-первых, я не знаю, что такое "сервер" в вашем коде, но я бы ожидал, что он будет асинхронным, поэтому в вашей функции setUp будет нечто подобное:
function (callback) {
server.StartServer(function(){
callback();
});
}
Во-вторых, не забывайте, что nodeunit выполняет функции startUp и tearDown после и перед КАЖДЫМ тестом, поэтому я подозреваю, что вы запускаете свой сервер 2 раза (как в tearDown, вы его не закрываете).
Последние пару часов я потратил на решение этой проблемы, и стало ясно, что узел узла не может перехватывать и отображать исключения, возникающие в функциях, которые позже запускаются процессом типа IO или setTimeout. Учитывая то, как работает JavaScript, это не удивительно. Все работает, если вы уверены, что исключений нет, но если в вашем коде есть ошибка, вы получите сообщение "отменить тесты" и больше ничего. Вот что я сделал для решения своих проблем (на примере маршрута 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);
}
}
Однажды я понял проблему таким образом, исправив ее, потому что стал намного понятнее, и я смог пройти все свои тесты!
Я подозреваю, что вы на самом деле не звоните test.done()
в этом втором тесте. Положить console.log()
позвоните туда, чтобы убедиться, что вы действительно делаете этот звонок.
Я повторил описанную проблему, используя упрощенную версию вашего теста ниже. Если вы опустите on('error', function() {...})
обработчик, то 2-й тест не может быть завершен. Таким образом, моя теория заключается в том, что ваш /push
конечная точка вызывает другое поведение в модуле restify. Т.е. вы уверены, что restify вызывает ваш обратный вызов с err
собственность там, или она делает что-то другое? ... как, например, излучение события, как 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();
});
};
Я работаю над этим, разветвляя сервер в его собственный процесс в настройке, а затем убивая его в демонтаже. Думаю, проблема заключалась в том, что сервер был создан, а не выключен. Спасибо @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();
});
}
};