La fonction Async dans mocha avant () est toujours terminée avant it () spec?

89

J'ai une fonction de rappel dans before()laquelle est pour nettoyer la base de données. Tout est-il before()garanti pour finir avant le it()début?

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(){
});
Nicolas S.Xu
la source
1
Cela devrait fonctionner. Vous devez juste vous assurer de renvoyer une promesse de votre beforegestionnaire. Egbefore(function () { return db.collection...}
broofa

Réponses:

125

Pour les nouvelles versions moka:

Vous pouvez maintenant retourner une promesse au moka, et moka attendra qu'elle se termine avant de continuer. Par exemple, le test suivant réussira:

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

Vous pouvez trouver la documentation ici

Pour les anciennes versions de moka:

Si vous souhaitez que votre demande asynchrone soit terminée avant que tout le reste ne se produise, vous devez utiliser le doneparamètre dans votre demande avant et l'appeler dans le rappel.

Mocha attendra alors d' doneêtre appelé pour commencer à traiter les blocs suivants.

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

Vous devez cependant faire attention, car ne pas stubbing la base de données pour les tests unitaires peut fortement ralentir l'exécution, car les requêtes dans une base de données peuvent être assez longues par rapport à une simple exécution de code.

Pour plus d'informations, consultez la documentation Mocha .

Clément Berthou
la source
Notez que si l'opération asynchrone prend trop de temps, vous obtiendrez un message d'échec qui n'est pas très utile: stackoverflow.com/a/48087201/1827734
BrDaHa
Mocha prend désormais en charge les promesses dans les hooks - mochajs.org/#working-with-promises . Pas besoin d'utiliser done. Renvoyez simplement une promesse.
broofa
Vous pouvez aussi: before(function () { return db.collection('user').remove({}); })depuis remove()renvoie une promesse, pas besoin de l'envelopper dans unnew Promise()
Brent Greeff
7

Espérons que votre db.collection () devrait renvoyer une promesse. Si oui, vous pouvez également utiliser le mot-clé async dans before ()

// 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()
});
Mandeep Singh
la source
4
Et pour after()? Mon awaitfonctionne bien lorsque je l'appelle before()(il supprime une entrée de base de données), mais si je mets exactement la même chose after(), il ne supprime rien au moment où une seconde describe()...it()commence et échoue en raison de la non suppression des données.
Juha Untinen