【问题标题】:Test will not call done() when failing测试失败时不会调用 done()
【发布时间】:2017-10-04 09:52:54
【问题描述】:

我正在编写一个单元测试来测试我的 postgres 架构。我正在使用 node-pg、mocha、sinon 和 chai。

这行得通 - 测试通过,没有问题:

describe('When adding a user', ()=> {
  it('should reject since email is used somewhere else', (done)=> {
    pool.query(`INSERT INTO users(email, id, token)
               VALUES($1, $2, $3)`, ['foo@email.com', '12346', 'fooToken'])
    .then((result)=> {
      console.log('nothing in here runs, you will not see this');
      done()
    })
    .catch((result) => {
      result.constraint.should.have.string('email_already_exists');
      done();
    })
  })
});

但为了确保我没有得到误报,我将断言更改为 result.constraint.should.not.have.string('email_already_exists'); 以故意使测试失败。

我得到的是Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.,而不是测试失败。

我得到了什么?

【问题讨论】:

  • 如果您正在测试基于 Promise 的代码,您应该考虑使用 Mocha 的内置 promises support。预防此类问题要容易得多。
  • @robertklep 如何在节点中测试 2 次获取时使用此承诺支持? stackoverflow.com/questions/43690868/…
  • 一个很好的例子:coderwall.com/p/axugwa/…
  • @dman 在那个问题中,您从一开始就不能很好地测试的代码开始。例如,index.js 运行的代码不会以任何方式暴露给“外部世界”。
  • @dman 见this gist

标签: node.js postgresql unit-testing mocha.js chai


【解决方案1】:

如果您仍然想为此使用 Promises,那么问题是 Promises 中未处理的异常很遗憾没有被传播,而是被默默地忽略了。结果没有人调用Mocha的done方法,导致超时。

将侦听器附加到 Node 的 unhandledRejection 事件(如文档中的 here 所示)应该可以证明这一点。

如果您修改原始代码并添加对 Promise 的 done 方法的调用(这不是 Mocha 的 done 方法!),那么您将能够捕获所有错误并将它们传递给 Mocha 的 @987654327 @方法:

it('tests something', done => {
    pool.query('...')
    .then(result => {
        // ...
     })
    .catch(result => {
        // assertion that fails
    })
    .done(result => {}, error => { done(error); });
});

请注意,Promise.done() (还)不是标准的一部分,但仍然受到许多实现的支持。参见例如here

【讨论】:

    【解决方案2】:

    答案:

    node-pg 的 Promise 链在 测试期间导致了这个奇怪的问题。如果我使用回调,那么没有问题:

    describe('When adding a user', ()=> {
      it('should reject since email is used somewhere else', (done)=> {
        function callback(err, result) {
          err.constraint.should.not.have.string('email_already_exists');
          done();
        }
        pool.query(`INSERT INTO users(email, id, token)
                   VALUES($1, $2, $3)`, ['foo@email.com', '12346', 'fooToken'], callback)
      })
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 2015-06-30
      • 2019-10-17
      • 1970-01-01
      相关资源
      最近更新 更多