Fungsi asinkron di mocha sebelum () selalu selesai sebelum itu () spec?

89

Saya memiliki fungsi panggilan balik before()untuk membersihkan database. Apakah semuanya before()dijamin selesai sebelum it()dimulai?

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
sumber
1
Ini seharusnya berhasil. Anda hanya perlu memastikan bahwa Anda membalas janji dari beforepawang Anda . Misalnyabefore(function () { return db.collection...}
broofa

Jawaban:

126

Untuk versi baru moka:

Sekarang Anda dapat mengembalikan janji ke moka, dan moka akan menunggunya selesai sebelum melanjutkan. Misalnya, tes berikut akan lulus:

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

Anda dapat menemukan dokumentasinya di sini

Untuk versi mocha yang lebih lama:

Jika Anda ingin permintaan asinkron Anda diselesaikan sebelum hal lainnya terjadi, Anda perlu menggunakan doneparameter dalam permintaan sebelum Anda, dan memanggilnya di callback.

Mocha kemudian akan menunggu hingga donedipanggil untuk mulai memproses blok berikut.

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

Anda harus berhati-hati, karena tidak menghentikan database untuk pengujian unit dapat sangat memperlambat eksekusi, karena permintaan dalam database mungkin cukup lama dibandingkan dengan eksekusi kode sederhana.

Untuk informasi lebih lanjut, lihat dokumentasi Mocha .

Clément Berthou
sumber
Perhatikan bahwa jika operasi asinkron memakan waktu terlalu lama, Anda akan mendapatkan pesan kegagalan yang tidak terlalu membantu: stackoverflow.com/a/48087201/1827734
BrDaHa
Mocha sekarang mendukung promise di hooks - mochajs.org/#working-with-promises . Tidak perlu digunakan done. Kembalikan saja janji.
broofa
Anda juga dapat: before(function () { return db.collection('user').remove({}); })karena remove()mengembalikan janji, tidak perlu membungkusnya dengannew Promise()
Brent Greeff
7

Mudah-mudahan db.collection () Anda harus mengembalikan janji. Jika ya maka Anda juga dapat menggunakan kata kunci async di 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
sumber
4
Bagaimana dengan after()? Saya awaitbekerja dengan baik ketika saya memanggilnya before()(itu menghapus entri DB), tetapi jika saya memasukkan hal yang sama persis after(), itu tidak menghapus apa pun pada saat satu detik describe()...it()dimulai dan gagal karena data tidak dihapus.
Juha Untinen