mocha before() 中的异步函数总是在 it() 规范之前完成?

Posted

技术标签:

【中文标题】mocha before() 中的异步函数总是在 it() 规范之前完成?【英文标题】:Async function in mocha before() is alway finished before it() spec? 【发布时间】:2014-09-03 14:13:35 【问题描述】:

我在before() 中有一个用于清理数据库的回调函数。 before() 中的所有内容都保证在 it() 开始之前完成吗?

before(function()
   db.collection('user').remove(, function(res)); // is it guaranteed to finish before it()? 
);

it('test spec', function(done)
  // do the test
);

after(function()
);

【问题讨论】:

这应该可以。您只需要确保从您的before 处理程序返回一个承诺。例如。 before(function () return db.collection... 【参考方案1】:

对于新的 mocha 版本:

您现在可以向 mocha 返回一个承诺,mocha 将等待它完成后再继续。例如,以下测试将通过:

let a = 0;
before(() => 
  return new Promise((resolve) => 
    setTimeout(() => 
      a = 1;
      resolve();
    , 200);
  );
);
it('a should be set to 1', () => 
  assert(a === 1);
);

您可以找到文档here

对于较旧的 mocha 版本:

如果您希望异步请求在其他一切发生之前完成,您需要在之前的请求中使用done 参数,并在回调中调用它。

Mocha 将等到调用done 开始处理以下块。

before(function (done) 
   db.collection('user').remove(, function (res)  done(); ); // It is now guaranteed to finish before 'it' starts.
)

it('test spec', function (done) 
  // execute test
);

after(function() );

您应该小心,因为不为单元测试存根数据库可能会大大减慢执行速度,因为与简单的代码执行相比,数据库中的请求可能相当长。

有关详细信息,请参阅Mocha documentation。

【讨论】:

请注意,如果异步操作耗时过长,您将收到一条帮助不大的失败消息:***.com/a/48087201/1827734 Mocha 现在支持钩子中的承诺 - mochajs.org/#working-with-promises。无需使用done。只需返回一个承诺。 你也可以:before(function () return db.collection('user').remove(); ),因为remove()返回一个promise,不需要用new Promise()包装它【参考方案2】:

希望您的 db.collection() 应该返回一个承诺。如果是,那么您也可以在 before() 中使用 async 关键字

// Note: I am using Mocha 5.2.0.
before(async function()
   await db.collection('user').remove(, function(res)); // it is now guaranteed to finish before it()
);

【讨论】:

after() 怎么样?当我在before() 中调用它时,我的await 工作正常(它会删除一个数据库条目),但如果我将完全相同的东西放入after(),它不会在第二个describe()...it() 开始时删除任何内容并且由于未删除数据而失败。【参考方案3】:

您可以使用 IIFE(立即调用函数表达式)。

这是一个例子:

before(function () 
    (async () => 
        try 
            await mongoose.connect(mongo.url,  useNewUrlParser: true, useUnifiedTopology: true );
         catch (err) 
            console.log(err);
        
    )();
);

【讨论】:

以上是关于mocha before() 中的异步函数总是在 it() 规范之前完成?的主要内容,如果未能解决你的问题,请参考以下文章

为啥传递的函数是不是带参数对 Mocha 的 `before()` 很重要?

在整个 mocha 测试之前运行异步代码

在mocha测试中调用异步函数如何避免超时错误:超过2000ms的超时

使用 Mocha 测试是不是抛出异步函数

Mocha,应该 - 在测试具有承诺的异步函数时,断言错误是沉默的

使用 mocha 和 chaiAsPromised 测试异步函数时的断言错误