使用superagent + promises的摩卡测试超时而不是以'expect'失败
我使用mocha
来针对外部Web服务运行一些集成测试。我使用superagent-promise
作为请求/响应处理,并且我使用expect
作为我的断言库。使用superagent + promises的摩卡测试超时而不是以'expect'失败
对于其中一些测试,我需要将大量请求链接在一起,所以承诺非常有帮助。但是我注意到我的测试现在失败了,并且发生了超时错误(而没有错误信息),而不是错误信息本身。举个简单的例子:
it('[MESSAGES-1] cannot be posted without an auth token', function(done) {
agent.post(config.webRoot + '/rooms/ABC/messages').send({
content: 'This is a test!'
}).end().then(function(res) {
// Not expected
}, function(err) {
expect(err.status).toBe(401)
done()
})
})
按预期工作,并传递:
Messages
✓ [MESSAGES-1] cannot be posted without an auth token
然而,如果我改变我的说法,期待一个不同的状态代码:
expect(err.status).toBe(200) // This should fail
然后测试超时失败!
1) Messages [MESSAGES-1] cannot be posted without an auth token:
Error: timeout of 1000ms exceeded. Ensure the done() callback is being called in this test.
这是常见问题吗?是否有解决办法或调整我可以做?我不想失去使用承诺的能力。
这是已知的问题吗?
这实际上不是问题。
问题是expect(err.status).toBe(200)
在.then
内部引发了吞噬错误,导致代码永远无法到达done()
。你应该重构你的代码如下:
it('[MESSAGES-1] cannot be posted without an auth token', function(done) {
agent.post(config.webRoot + '/rooms/ABC/messages').send({
content: 'This is a test!'
}).end()
.then(function(res) {
// Not expected
}, function(err) {
expect(err.status).toBe(401)
done()
})
.catch(function(err) {
done(err); //report error thrown in .then
})
})
这样你赶上并报告expect(err.status).toBe(200)
抛出的错误。
在你的情况下,超时发生,因为完成的回调从不被调用,要么是因为http请求没有失败,要么期望失败,所以它抛出了断言错误。
摩卡处理正确的(承诺返回)异步测试,所以不要使用完成的回调,它会导致混淆与承诺混淆。相反地返回承诺:
it('[MESSAGES-1] cannot be posted without an auth token', function() {
return agent.post(config.webRoot + '/rooms/ABC/messages').send({
content: 'This is a test!'
}).end().then(function(res) {
// here you must throw an error, because if the post didnt fail somehow, the test would be green because of no assertations and no promise rejection.
throw new Error("Not expected");
}, function(err) {
expect(err.status).toBe(401);
});
});
“* ...或者是因为http请求没有失败...... *”OP明确指出,他对代码的唯一更改是将expect(err.status).toBe(401)'更改为'expect(err .STATUS).toBe(200)'。基于这个前提,问题在于抛出的断言错误会阻止'.then'承诺内的代码的执行 - 在OP的代码中被承诺吞噬的错误(正如我的回答中所述)。 – rabbitco
@rabbitco这就是为什么你在处理promise时不应该使用'done',并让Mocha正确处理它们的原因。 – robertklep
@robertklep:同意 – rabbitco
就是这样!我是JavaScript的新承诺 - 我没有意识到catch(),但它完美地工作。 –