Funkcja asynchroniczna w mokce przed () jest zawsze zakończona przed () specyfikacją?

89

Mam funkcję zwrotną, w before()której służy do czyszczenia bazy danych. Czy wszystko na before()pewno skończy się przed it()startem?

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
źródło
1
To powinno działać. Musisz tylko upewnić się, że zwrócisz obietnicę od swojego beforeopiekuna. Np.before(function () { return db.collection...}
broofa

Odpowiedzi:

126

Nowe wersje mokki:

Możesz teraz zwrócić obietnicę mokce, a mokka będzie czekać na jej zakończenie, zanim przejdziesz dalej. Na przykład następujący test przejdzie:

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

Dokumentację znajdziesz tutaj

Dla starszych wersji mokki:

Jeśli chcesz, aby asynchroniczne żądanie zostało zakończone, zanim wszystko inne się wydarzy, musisz użyć doneparametru w swoim przed żądaniu i wywołać go w wywołaniu zwrotnym.

Mocha będzie wtedy czekać, aż donezostanie wezwana do rozpoczęcia przetwarzania kolejnych bloków.

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

Należy jednak zachować ostrożność, ponieważ niezastosowanie bazy danych do testów jednostkowych może znacznie spowolnić wykonywanie, ponieważ żądania w bazie danych mogą być dość długie w porównaniu z prostym wykonaniem kodu.

Aby uzyskać więcej informacji, zobacz dokumentację Mocha .

Clément Berthou
źródło
Zwróć uwagę, że jeśli operacja asynchroniczna trwa zbyt długo, otrzymasz komunikat o błędzie, który nie jest zbyt pomocny: stackoverflow.com/a/48087201/1827734
BrDaHa
Mocha obsługuje teraz obietnice w hakach - mochajs.org/#working-with-promises . Nie ma potrzeby używania done. Po prostu złóż obietnicę.
broofa
Możesz także: before(function () { return db.collection('user').remove({}); })ponieważ remove()zwraca obietnicę, nie musisz jej zawijaćnew Promise()
Brent Greeff
7

Miejmy nadzieję, że twoja db.collection () powinna zwrócić obietnicę. Jeśli tak, możesz również użyć słowa kluczowego async w 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
źródło
4
Co powiesz na to after()? Moje awaitdziała dobrze, kiedy before()go wywołuję (usuwa wpis DB), ale jeśli umieszczę dokładnie to samo after(), nie usuwa niczego do czasu rozpoczęcia sekundy describe()...it()i kończy się niepowodzeniem z powodu braku usunięcia danych.
Juha Untinen