无法从超级应用程序请求中捕获exception

代码示例如下所示: https : //gist.github.com/sebinsua/8118001

(有三次失败,两次失败,我希望有四次失败,一次成功。)

如果从正常函数抛出,可以用摩卡来捕获AssertionErrors,但是一旦超级包装的应用程序调用函数,我就不能检测到它们。 这是烦人的,因为我想能够注入某些断言到我的快速应用程序,然后我可以testing。 (我正在testing一个有我想testing的副作用的中间件,如果你能告诉我如何模拟请求和响应对象,也可以解决我的问题。)

因为我能够进入间谍,我知道这与国家无法进入无关。

不过,我注意到node.js / express.js / supertest自动将未捕获的exception转换为响应中的错误消息。 也许这就是阻止他们被摩卡testing抓住的原因?

编辑

我刚刚testing了下面的代码,看看这是否是一个普通的http.createServer()问题。 事实并非如此。 这意味着连接,express.js,超级或超级等级都会发生。 (这些代码片段只能工作一半的时间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没有出现在红色的文本中(就像在摩卡拾起的情况下一样)。

 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?

一个

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

UPDATE

在/lib/proto.js中senchalab的连接192行就是这样的地方。 有一个try-catch,这将我的错误传递到下一个中​​间件,它继续做同样的事情,直到4元中间件处理它,或没有更多的中间件,它运行一些后备代码自动打印到屏幕上并抛弃exception…

我不知道我能做些什么来让它再次抛出我的错误,除非我能够覆盖处理方法或其他。

你问:

不过,我注意到node.js / express.js / supertest自动将未捕获的exception转换为响应中的错误消息。 也许这就是阻止他们被摩卡testing抓住的原因?

是的,这就是HTTP服务器默认情况下的工作原理:对服务器软件没有任何特殊含义的exception转换为状态500响应。 所以,如果你想testing服务器已经抛出exception,你可以自己logging这个事实,并在以后使用它。 例如:

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

这是为了说明原则。 catcherfunction可以被devise成足够通用的,以适用于大量不同的testing。