【问题标题】:Mocha: how to assert a promise rejection?Mocha:如何断言一个承诺拒绝?
【发布时间】:2019-01-17 06:50:56
【问题描述】:

我正在尝试让 Mocha 显示错误,并在我的 Node 代码上声明一个被拒绝的承诺 - ...而不是为导致我的异步函数被拒绝的异常显示 UnhandledPromiseRejectionWarning

我已经搜索并尝试了许多关于在 Mocha 中处理此警告和承诺拒绝的建议,但没有一个对我有用。这似乎是一个反复出现的话题,对很多人来说都是一个非常困惑的话题。

我正在尝试这样做:

  • 使用 lambda 函数

  • 不使用done

  • 使用简单的断言(我不喜欢expectshould

  • 通过 try/catch 处理错误(我不喜欢链式 .then.catch;如果使用 .then(res,err) 则更不喜欢它)

类似:

it('should give an error', 
  async ()=> {
    try{
      await generateException()
      assert(true)
    } catch(err) {
      console.err(err)
      assert ??? // how to 'assert' a promise rejection?
    }
  }
)

如果不可避免地要使用我不太喜欢的任何东西,那很好。但是我想要的更接近的解决方案是什么?

另外,我不明白为什么被拒绝的承诺不会像我预期的那样被 try/catch 捕获,因为这正是使用 await 的目的(使异步代码像它们一样工作)同步)。

【问题讨论】:

    标签: javascript promise async-await mocha.js


    【解决方案1】:

    使用 mocha 单元测试

    断言节点模块: 这是我的建议:

    const assert = require('assert');
    
    const PromiseFail = async (proms) => await assertPromise(proms, false);
    const PromiseSucced = async (proms) => await assertPromise(proms);
    const assertPromise = async (prom, succed = true) => {
        succed = succed ? true : false;
        try {
            prom = Array.isArray(prom) ? prom : [prom];
            await Promise.all(prom);
            assert.strictEqual(true, succed);
        }
        catch (ex) { assert.notStrictEqual(true, succed, ex); }
    }
    

    测试时:

    describe('unit test', () => {
     it('test 1', async () => {
            await PromiseSucced(Promise.resolve(1))
            await PromiseSucced([Promise.resolve(2), Promise.resolve(3)])
            const promise4 = new Promise((resolve, reject) => {
                setTimeout(reject, 100, 'foo');
            });
            await PromiseFail(promise4)
        });
    })
    

    【讨论】:

      【解决方案2】:

      使用assert 库测试承诺拒绝非常简单

      import { strict as assert } from 'assert'
      it('should give an error', async function () {
          await assert.rejects(generateException())
      })
      

      如果您需要打印错误,您可以这样做

      import { strict as assert } from 'assert'
      it('should give an error', async function () {
          await assert.rejects(generateException()).catch((err) => {
              console.err(err)
              throw err
          }
      })
      

      【讨论】:

        【解决方案3】:

        这对我有用。例如,使用 chai 进行断言。

        const chai = require('chai');
        const expect = chai.expect;
        
        describe('test', function () {
        
          function generateException() {
            throw new Error('test error');
          }
        
        
          it('should give an error', async ()=> {
            try {
              await generateException();
              expect(true).to.be.false;
            } catch(err) {
              console.log(err.message);
              expect(err.message).to.equal('test error');
            }
          })
        })
        

        Promise.reject()throw new Error() 的使用方式似乎有所不同。当函数generateException 抛出错误时,您的测试将起作用。 但是,如果它是 Promise.reject(),它永远不会到达 catch 块。

        如果您执行let result = await generateException(); 之类的操作,您将看到如果geenerateException 函数使用promise reject,您会看到这是您所期望的错误。

        如果你愿意,你可以用 await 链接 promise。

        function generateException() {
          return new Promise(reject => {
           return reject(new Error('Promise Rejected');
        })
        
        it('should give an error', async ()=> {
          await generateException().catch(error => {
            expect(error.message).to.equal('Promise Rejected');
        
          })
        });
        

        阅读this article on async code 的部分内容可能会有所帮助。

        【讨论】:

        • 我想我(和许多其他人)正在努力的部分是理解“为什么?!” Promise.reject() 永远不会到达 catch 块...
        • medium.com/@yamalight/… 可能会对此有所了解。
        • 但是这篇文章实际上在“选项 1”中说 try/catch 应该捕获错误......那么,为什么不也是 mocha 示例呢?
        猜你喜欢
        • 2017-07-16
        • 2014-07-16
        • 2015-10-28
        • 1970-01-01
        • 1970-01-01
        • 2022-11-22
        • 2019-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多