【问题标题】:expecting promised to resolve or reject doesn't properly fail a test with mocha and chai-as-promised期望承诺解决或拒绝并不能正确地通过 mocha 和 chai-as-promised 的测试
【发布时间】:2018-06-01 01:02:28
【问题描述】:

使用Mocha 和chai-as-promised,我正在尝试测试我的承诺是否被正确解决和拒绝。但是 chai-as-promised 提供的 expect 函数并没有正确地导致测试失败。示例:

test.js

const chai = require('chai')
chai.use(require('chai-as-promised'))
const expect = chai.expect

describe('foo', () => {
  it('resolve expected', () => {
    expect(new Promise((res,rej) => {res()})).to.be.fulfilled
  })
  it('resolve unexpected', () => {
    expect(new Promise((res,rej) => {res()})).to.be.rejected
  })
  it('reject expected', () => {
    expect(new Promise((res,rej) => {rej()})).to.be.rejected
  })
  it('reject unexpected', () => {
    expect(new Promise((res,rej) => {rej()})).to.be.fulfilled
  })
})

当我执行mocha test.js:

  foo
    ✓ resolve expected
    ✓ resolve unexpected
(node:2659) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: expected promise to be rejected but it was fulfilled with undefined
(node:2659) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    ✓ reject expected
    ✓ reject unexpected
(node:2659) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): AssertionError: expected promise to be fulfilled but it was rejected with undefined


  4 passing (10ms)

您可以看到断言错误似乎被抛出,但 mocha 没有拾取它们。如何让 mocha 识别失败?

【问题讨论】:

  • 我认为您应该返回expect 电话。您是否尝试在每个测试中添加 return 关键字?
  • 我刚刚试了一下。有用。但是现在我想知道您是如何将多个 expect 语句放入一个测试中的?
  • 我不确定,我有一段时间没有使用 chai-promise 库了。
  • 您能否接受该解决方案,以便其他人更容易找到答案。另外,如果您回答第二个问题,请告诉我,我可以更新解决方案:)

标签: javascript node.js mocha.js chai chai-as-promised


【解决方案1】:

正如我们确认的那样,为了将来参考,问题在于您没有在每个测试中返回断言。

it('reject expected', () => {
  return expect(new Promise((res,rej) => {rej()})).to.be.rejected
})
it('reject unexpected', () => {
  return expect(new Promise((res,rej) => {rej()})).to.be.fulfilled
})

这就是为什么测试通过但后来在它最终返回时打印了一个“未处理”的承诺。 return 关键字通知 mocha 等待异步函数解析/拒绝。

【讨论】:

    【解决方案2】:

    或者使用 chai-as-promised 库,您可以尝试使用 chai.should 并调用 .notify 来指示其“完成”。像这样:

    const chai = require('chai');
    chai.use(require('chai-as-promised'));
    chai.should();
    
    const expect = chai.expect;
    
    describe('foo', () => {
        it('resolve expected', () => {
            expect(new Promise((res, rej) => { res(); })).to.be.fulfilled;
        });
        it('resolve unexpected', (done) => {
            // expect(new Promise((res, rej) => { res(); })).to.be.rejected;
            new Promise((res, rej) => { res(); }).should.be.rejected.and.notify(done);
        });
        it('reject expected', (done) => {
            // expect(new Promise((res, rej) => { rej(); })).to.be.rejected;
            new Promise((res, rej) => { rej(); }).should.be.rejected.and.notify(done);
        });
        it('reject unexpected', (done) => {
            // expect(new Promise((res, rej) => { rej(); })).to.be.fulfilled;
            new Promise((res, rej) => { rej(); }).should.be.fulfilled.and.notify(done);
        });
    });
    

    这样 mocha 会识别测试失败:

    foo
        √ resolve expected
        1) resolve unexpected
        √ reject expected
        2) reject unexpected
    
    
      2 passing (37ms)   2 failing
    
      1) foo
           resolve unexpected:
         AssertionError: expected promise to be rejected but it was fulfilled with undefined
    
    
      2) foo
           reject unexpected:
         AssertionError: expected promise to be fulfilled but it was rejected with undefined
    

    查看 chai-as-promised 文档以获取更多参考 here

    【讨论】:

    • 只需返回承诺:比使用done 更简单、更干净。
    • 是的,同意你@Louis。我上面的建议只是为了展示如何使用 chai-as-promise 的不同风格,并且由于 ewok 询问如何在一个测试中放置多个断言,因此在这种情况下不可能使用“return”。如果我们想在测试 Promise 时放置多个断言,使用 'done' 可能会起作用,但我确实认为我们应该有单独的 'it' 来测试特定情况。
    【解决方案3】:
     it ('creates images', async () => {
          
          assert.equal(imageCount,1)
          const event = result.logs[0].args
          assert.equal(event.id.toNumber(),imageCount.toNumber(),'id is correct')
          assert.equal(event.hash,hash,'Hash is correct')
          assert.equal(event.description,'Image Description','description is correct')
          assert.equal(event.tipAmount,'0','tip amount is correct')
          assert.equal(event.author, author, 'author is correct')
    
          await decentragram.uploadImage('','Image description', { from: author }).should.be.rejected;
          await decentragram.uploadImage('Image hash','', { from:author }).should.be.rejected;
        })
    

    在这里面临同样的问题。但同意 [luke-stoward][1]

    解决方案:添加返回

    it ('creates images', async () => {
         return
          assert.equal(imageCount,1)
          const event = result.logs[0].args
          assert.equal(event.id.toNumber(),imageCount.toNumber(),'id is correct')
          assert.equal(event.hash,hash,'Hash is correct')
          assert.equal(event.description,'Image Description','description is correct')
          assert.equal(event.tipAmount,'0','tip amount is correct')
          assert.equal(event.author, author, 'author is correct')
    
          await decentragram.uploadImage('','Image description', { from: author }).should.be.rejected;
          await decentragram.uploadImage('Image hash','', { from:author }).should.be.rejected;
        })
    

    【讨论】:

    • 我认为添加 return 会使下面的代码无法访问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 2014-07-22
    • 2020-09-14
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    相关资源
    最近更新 更多