Asynchrone Funktion in Mokka vor () ist immer beendet, bevor es () spezifiziert?

88

Ich habe eine Rückruffunktion before()zum Reinigen der Datenbank. Ist before()garantiert, dass alles vor dem it()Start fertig ist ?

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.
quelle
1
Das sollte funktionieren. Sie müssen nur sicherstellen, dass Sie ein Versprechen von Ihrem beforeHandler zurückgeben. ZBbefore(function () { return db.collection...}
Broofa

Antworten:

125

Für neue Mokka-Versionen:

Sie können jetzt ein Versprechen an Mokka zurückgeben, und Mokka wartet, bis es abgeschlossen ist, bevor Sie fortfahren. Der folgende Test besteht beispielsweise:

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

Die Dokumentation finden Sie hier

Für ältere Mokka-Versionen:

Wenn Sie möchten, dass Ihre asynchrone Anforderung abgeschlossen wird, bevor alles andere passiert, müssen Sie den doneParameter in Ihrer vorherigen Anforderung verwenden und ihn im Rückruf aufrufen.

Mocha wartet dann, bis doneaufgerufen wird, um mit der Verarbeitung der folgenden Blöcke zu beginnen.

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

Sie sollten jedoch vorsichtig sein, da ein Nicht-Stubben der Datenbank für Unit-Tests die Ausführung stark verlangsamen kann, da Anforderungen in einer Datenbank im Vergleich zur einfachen Codeausführung ziemlich lang sein können.

Weitere Informationen finden Sie in der Mokka-Dokumentation .

Clément Berthou
quelle
Beachten Sie, dass, wenn der asynchrone Vorgang zu lange dauert, eine Fehlermeldung angezeigt
BrDaHa
Mocha unterstützt jetzt Versprechen in Haken - mochajs.org/#working-with-promises . Keine Notwendigkeit zu verwenden done. Gib einfach ein Versprechen zurück.
Broofa
Sie können auch: before(function () { return db.collection('user').remove({}); })Da remove()ein Versprechen zurückgegeben wird, müssen Sie es nicht in einnew Promise()
Brent Greeff
7

Hoffentlich sollte Ihre db.collection () ein Versprechen zurückgeben. Wenn ja, können Sie auch das asynchrone Schlüsselwort in before () verwenden.

// 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
quelle
4
Wie wäre es für after()? Mein awaitfunktioniert einwandfrei, wenn ich before()es aufrufe (es löscht einen DB-Eintrag), aber wenn ich genau dasselbe einfüge after(), löscht es zu describe()...it()Beginn einer Sekunde nichts und schlägt fehl, weil die Daten nicht entfernt werden.
Juha Untinen