【问题标题】:How to use async-await and then in one Mocha test with done?如何使用 async-await 然后在完成的 Mocha 测试中使用?
【发布时间】:2019-08-26 05:16:45
【问题描述】:

所以,我有这样的测试:

it 'sample test', (done)->
    await Promise.resolve 0
    Promise.resolve 0
    .then ->
        done()
    null

注意,null 到底是为了避免返回 Promise。 但是,测试属于经典"Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both"

我检查了结果JS代码,没有什么奇怪的:

it('Sample test', async function(done) {
    await Promise.resolve(0);
    Promise.resolve(0).then(function() {
      return done();
    });
    return null;
});

我不明白,出了什么问题,因为(我认为)这段代码不应该返回承诺。 另外,当我将第一个承诺(使用await)包装到setTimeout 中时,它工作正常。

it 'working test', (done)->
    setTimeout ->
        await Promise.resolve 0
    , 0
    Promise.resolve 0
    .then ->
        done()
    null

当然,使用setImmediate 而不是setTimeout 它也可以,所以我认为,在这种情况下,治疗方法是回调。但这是非常肮脏的解决方案。 如何在一个测试中更清晰地混合thenasync-awaitdone

【问题讨论】:

    标签: javascript async-await coffeescript mocha.js es6-promise


    【解决方案1】:

    在 Mocha v3.0.0 及更高版本中,返回 Promise 并调用 done() 将导致异常,因为这通常是一个错误 - docs

    由于async function always return Promise 您收到此错误。 可能的解决方案:

    • 删除async function

      it('Sample test', function(done) {
          Promise.resolve(0)
              .then(function() {
                  ...
              })
              .then(function() {
                  ... // if necessary
              }) 
              .then(function() {
                  done();
              });
      });
      
    • 返回Promise

      it('Sample test', function() {
          return Promise.resolve(0)
              .then(function() {
                  ...
              })
              .then(function() {
                  ... // if necessary
              });
      });
      
    • 使用async/await

      it('Sample test', async function() {
         await Promise.resolve(0);
         await Promise.resolve(0);
      });
      

    【讨论】:

      【解决方案2】:

      在函数体中使用await会将测试函数变成async函数。

      async functions 总是返回 Promise

      所以在这种情况下:

      it('Sample test', async function(done) {
          await Promise.resolve(0);
          Promise.resolve(0).then(function() {
            return done();
          });
          return null;
      });
      

      ...测试函数返回一个Promise,它将解析为null


      在您的另一个示例中,Mocha 没有抱怨,因为代码编译为:

      it('working test', function(done) {
        setTimeout(async function() {
          return (await Promise.resolve(0));
        }, 0);
        Promise.resolve(0).then(function() {
          return done();
        });
        return null;
      });
      

      ...因为await 现在位于传递给setTimeout 的函数体内。

      (请注意,这两个测试的行为非常不同)。


      没有理由同时使用 doneasync / await 测试函数(或返回 Promise 的函数),因此 Mocha 测试失败并出现该错误。

      您的第一个测试可以简化为:

      it 'sample test', ()->
          await Promise.resolve 0
          await Promise.resolve 0
      

      ...或者如果您需要在链接到第二个Promisethen 中工作,您可以这样做:

      it 'sample test', ()->
          await Promise.resolve 0
          await Promise.resolve 0
          .then ->
              // do stuff here
      

      【讨论】:

        猜你喜欢
        • 2017-07-19
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 2018-08-21
        • 1970-01-01
        • 1970-01-01
        • 2020-06-14
        相关资源
        最近更新 更多