【问题标题】:Mocha tests using superagent + promises timeout rather than fail with 'expect'使用 superagent + 承诺超时而不是因“期望”而失败的 Mocha 测试
【发布时间】:2017-03-26 14:23:37
【问题描述】:

我正在使用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.

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

【问题讨论】:

    标签: javascript promise mocha.js superagent


    【解决方案1】:

    这是一个已知问题吗?

    这实际上不是问题。

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

    【讨论】:

    • 就是这样!我是 JavaScript 中的 Promise 新手 - 我不知道 catch(),但它非常有效。
    【解决方案2】:

    在您的情况下,超时发生是因为从不调用 done 回调,或者是因为 http 请求没有失败,或者期望失败,所以它抛出了一个断言错误。

    Mocha 处理正确的(返回承诺的)异步测试,所以不要使用 done 回调,当与承诺混合时会导致混乱。改为返回承诺:

    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) 更改为 @987654323 @。基于这个前提,问题在于抛出的断言错误会停止执行.then 承诺中的代码 - OP 代码中的错误被承诺吞噬(如我的回答中所述)。
    • @rabbitco 这就是为什么在处理 Promise 时不应该使用 done,让 Mocha 正确处理它们。
    • @robertklep:同意
    猜你喜欢
    • 2016-04-24
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    相关资源
    最近更新 更多