使用Mocha和Supertest测试Express错误

时间:2016-02-23 20:24:15

标签: node.js express testing mocha supertest

我必须在接受测试中测试服务器错误(Express),这些测试不能(或不应该)与响应一起发送,例如

  

错误:发送后无法设置标头。

使用错误处理程序捕获错误并使用5XX代码进行响应将在此处提供有价值的反馈,但问题是标题已经发送。

这种错误可能是非关键的,很难发现,通常它们都是从日志中找出来的。

规范是

it('should send 200', function (done) {
    request(app).get('/').expect(200, done);
});

经过测试的应用

app.get('/', function (req, res, next) {
    res.sendStatus(200);
    next();
});

app.use(function (req, res) {
    res.sendStatus(200);
});

在类似情况下,Express app实例与请求测试库(即Supertest)之间进行通信的最合适方式是什么?

问题不仅限于Supertest。如果有包可以解决Supertest无法解决的问题,也可以考虑它们。

3 个答案:

答案 0 :(得分:1)

尝试只设置状态代码而不发送它,并避免发送两次,使用c1::c1(const c1 &)抛出错误。

正如express documentation所说的那样

  

设置响应的HTTP状态。它是可链接的别名   节点的res.status()

恕我直言,如果你想在端到端(E2E)测试工具中检测,例如response.statusCode(或 Selenium )您必须处理快速错误并发送正确的输出(500状态错误,某些消息......)以允许检测它。

或者使用unit test来测试控制器函数不会使用chai或本机断言抛出任何错误。

答案 1 :(得分:1)

我回答了类似的问题here。 “无法在设置后设置标头”错误应该通过表示为未处理的异常来引发。因此,您应该能够通过进程引发的 unhandledException 事件来访问它。

然而,由于时间安排,这更加棘手。在第一次res.statusCode调用之后,您的测试用例的期望函数和完成函数将排队等待在事件循环上进行处理。不幸的是,res.statusCode的下一次调用可能会在不确定的时间后发生。例如,如果第二个路由处理程序调用一个非常慢的Web服务或db然后调用res.statusCode,该怎么办?

考虑到这一点,你的选择非常困难。蛮力的方法是在测试代码中等待一段确定的时间,然后检查。它有效但缓慢且不确定,这将导致您的测试不稳定。

另一种选择是检查您在Express中可能具有的任何检测代码。如果您使用express中的代码来保存各种路由处理程序的进程调用数量指标,则可以将这些指标公开给测试代码。然后,您完成测试的一个条件是进程中路由调用的所有指标都是0.第二个选项将允许您编写确定性测试并且速度更快,因为您可以轮询指标。

最后的选择是通过单元测试来处理这个测试用例。这可能是最好的解决方案,因为它是确定性的,不需要任何类型的轮询。但是,缺点是您需要知道您的两个函数都按顺序调用,这会导致您尝试在测试代码中重新创建用于调用路由处理程序的逻辑。

答案 2 :(得分:-2)

我使用HAPI而不是Express来做到这一点,但我解决了同样的问题。我使用外部库来进行调用(如请求 - 承诺)并且它有效。在请求 - 承诺响应中捕获错误。