此处显示的代码示例:https://gist.github.com/sebinsua/8118001
(有三次失败和两次传球。我希望有四次失败,一次失败。)
如果从正常函数抛出,可以使用mocha捕获AssertionErrors,但是一旦从超级包装应用程序中调用函数,我就无法再检测到它们。这很烦人,因为我想能够将某些断言注入我的快速应用程序,然后我可以测试。 (我正在测试一个带有我希望测试的副作用的中间件,如果你能告诉我如何模拟请求和响应对象,这也解决了我的问题。)
因为我能够访问间谍,所以我知道这与无法访问的状态无关。
但是,我注意到node.js / express.js / supertest会自动将未捕获的异常转换为响应中的错误消息。也许这就是阻止他们被摩卡测试所困扰的原因?
修改
我刚刚测试了下面的代码,看看这是否是一般的http.createServer()问题。事实并非如此。这意味着在connect,express.js,supertest或superagent级别发生了一些事情。 (这些代码片段只能用于半个小时的btw ...)
var http = require("http"),
assert = require('assert');
describe('Really crazy test of assertions', function () {
it("cannot create a server which throws an assertion error", function (done) {
var port = Math.floor(Math.random() * 9999) + 1;
http.createServer(function (req, res) {
console.log("On the server.");
throw new assert.AssertionError({ message: "Can I throw an assertion error? "} );
res.end("HEY");
}).listen(port);
setTimeout(function () {
console.log("On the client.");
http.get('http://localhost:' + port + '/', function (res) {
console.log("Will I receive the error message on the client's side? No.");
console.log(res);
});
done();
}, 1000);
});
});
它看起来像一个明确的问题(见下文) - 我注意到AssertionError没有出现在红色文本中(就像被Mocha拾取一样)。
var http = require("http"),
express = require("express"),
assert = require('assert');
var app = express();
describe('Really crazy test of assertions', function () {
it("cannot create a server which throws an assertion error", function (done) {
var port = Math.floor(Math.random() * 9999) + 1;
app.get('/', function (req, res) {
console.log("On the server.");
throw new assert.AssertionError({ message: "Can I throw an assertion error? "} );
res.end('HEY');
}).listen(port);
setTimeout(function () {
console.log("On the client.");
http.get('http://localhost:' + port + '/', function (res) {
console.log("Will I receive the error message on the client's side? No.");
console.log(res);
});
done();
}, 1000);
});
});
简而言之,我的问题是,我如何让A表现得像B?
A
var http = require("http"),
express = require("express"),
assert = require('assert');
var app = express();
var port = Math.floor(Math.random() * 9999) + 1;
app.get('/', function (req, res) {
console.log("On the server.");
throw new assert.AssertionError({ message: "Can I throw an assertion error? "} );
res.send('HEY');
}).listen(8888);
乙
var http = require("http"),
assert = require('assert');
http.createServer(function (req, res) {
console.log("On the server.");
throw new assert.AssertionError({ message: "Can I throw an assertion error? "} );
res.end("HEY");
}).listen(8888);
更新
senchalab在/lib/proto.js上连接的第192行是出错的地方。有一个try-catch,这将我的错误传递给下一个中间件,它继续做同样的事情,直到4-arity中间件处理它或没有更多的中间件,它运行一些后备代码自动打印到屏幕并放弃例外......
我不知道我能做些什么来让它再次抛出我的错误,除非我能够覆盖句柄方法或其他方法。
答案 0 :(得分:1)
你问:
但是,我注意到node.js / express.js / supertest会自动将未捕获的异常转换为响应中的错误消息。也许这就是阻止他们被摩卡测试所困扰的原因?
是的,这几乎是HTTP服务器默认工作的方式:对服务器软件没有任何特殊含义的异常将转换为状态500响应。因此,如果您想测试服务器是否抛出了异常,您可以自己记录这个事实并在以后使用它。例如:
var http = require("http"),
express = require("express"),
assert = require('assert');
var app = express();
function handler (req, res) {
throw new assert.AssertionError({ message: "Can I throw an assertion error? "} );
res.end('HEY');
}
describe('Really crazy test of assertions', function () {
it("cannot create a server which throws an assertion error", function (done) {
var port = Math.floor(Math.random() * 9999) + 1;
var caught;
app.get('/', function catcher() {
try {
handler.apply(this, arguments);
}
catch (ex) {
caught = ex; // Capture it ...
throw ex; // ... and rethrow it.
}
}).listen(port);
setTimeout(function () {
http.get('http://localhost:' + port + '/', function (res) {
// Act on the caught exception, if it exists.
// This could be assert.equal or whatever.
if (caught)
throw caught;
done();
});
}, 1000);
});
});
这是为了说明原理。 catcher
函数可以设计得足够通用,可以用于一大堆不同的测试。