如何使用async-await,然后在一次Mocha测试中完成?

时间:2019-04-04 12:34:43

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

所以,我进行了这样的测试:

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;
});

我不明白,这是什么问题,因为(按照我的想法)此代码不应返回promise。 另外,当我将第一个承诺(带有await)包装到setTimeout中时,它可以正常工作。

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

当然,使用setImmediate而不是setTimeout也是可行的,因此,我认为这种情况下的解决方法是回调。但这是极其肮脏的解决方案。 如何在一个测试中更清楚地混合使用thenasync-awaitdone

2 个答案:

答案 0 :(得分:0)

在函数主体中使用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

...或者如果您需要在链接到第二个then的{​​{1}}中进行工作,只需执行以下操作:

Promise

答案 1 :(得分:0)

在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);
    });