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


89

我有一个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(){
});

1
这应该工作。您只需要确保您从before处理程序中返回了承诺即可。例如before(function () { return db.collection...}
broofa

Answers:


126

对于新的摩卡版本:

您现在可以将承诺返回给摩卡,摩卡将等待其完成后再继续。例如,以下测试将通过:

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

您可以在这里找到文档

对于较旧的摩卡版本:

如果希望异步请求在其他所有事情发生之前完成,则需要done在before请求中使用该参数,然后在回调中调用它。

然后,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文档


请注意,如果异步操作花费的时间太长,您将收到不是很有用的失败消息:stackoverflow.com/a/48087201/1827734
BrDaHa

摩卡现在支持钩子中的承诺-mochajs.org/#working-with-promises。无需使用done。只要兑现承诺即可。
broofa

您还可以:before(function () { return db.collection('user').remove({}); })由于remove()返回了承诺,因此无需将其包装在new Promise()
Brent Greeff

7

希望您的db.collection()应该返回一个promise。如果是,那么您还可以在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()
});

4
怎么样after()await当我调用它时before()(它删除了一个数据库条目),我的工作正常,但是如果将完全相同的内容放入after(),它不会在第二秒describe()...it()开始时删除任何内容,并且由于未删除数据而失败。
Juha Untinen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.