使用superagent + promises超时而不是失败的Mocha测试'expect'

时间:2016-11-12 13:46:51

标签: javascript promise mocha superagent

我正在使用mocha对外部Web服务运行许多集成测试。我使用superagent-promise进行请求/响应处理,我使用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.

这是一个常见问题吗?我可以做出解决方法或调整吗?我不想失去使用承诺的能力。

2 个答案:

答案 0 :(得分:2)

  

这是一个已知问题吗?

这实际上不是问题。

问题是,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)抛出的错误。

答案 1 :(得分:2)

在你的情况下,超时发生是因为从未调用完成回调,因为http请求没有失败,或者期望失败因此它引发了断言错误。

Mocha处理正确(承诺返回)异步测试,因此不要使用完成回调,它与promises混合时会引起混淆。返回承诺:

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