¿La función asíncrona en mocha before () siempre se termina antes de la especificación ()?

89

Tengo una función de devolución de llamada en la before()que es para limpiar la base de datos. ¿Está todo before()garantizado para terminar antes de que it()comience?

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
fuente
1
Esto debería funcionar. Solo necesita asegurarse de devolver una promesa de su beforecontrolador. Por ejemplobefore(function () { return db.collection...}
broofa

Respuestas:

126

Para nuevas versiones de moca:

Ahora puede devolver una promesa a mocha, y mocha esperará a que se complete antes de continuar. Por ejemplo, se aprobará la siguiente prueba:

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

Puedes encontrar la documentación aquí

Para versiones antiguas de moca:

Si desea que su solicitud asincrónica se complete antes de que suceda todo lo demás, debe usar el doneparámetro en su solicitud anterior y llamarlo en la devolución de llamada.

Mocha esperará entonces hasta que donesea ​​llamado para comenzar a procesar los siguientes bloques.

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

Sin embargo, debe tener cuidado, ya que no copiar la base de datos para las pruebas unitarias puede ralentizar mucho la ejecución, ya que las solicitudes en una base de datos pueden ser bastante largas en comparación con la ejecución de código simple.

Para obtener más información, consulte la documentación de Mocha .

Clément Berthou
fuente
Tenga en cuenta que si la operación asincrónica tarda demasiado, recibirá un mensaje de error que no es muy útil: stackoverflow.com/a/48087201/1827734
BrDaHa
Mocha ahora admite promesas en ganchos: mochajs.org/#working-with-promises . No es necesario usarlo done. Solo devuelve una promesa.
broofa
También puede: before(function () { return db.collection('user').remove({}); })dado que remove()devuelve una promesa, no es necesario envolverla en unnew Promise()
Brent Greeff
7

Con suerte, su db.collection () debería devolver una promesa. Si es así, también puede usar la palabra clave async en 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
fuente
4
¿Qué tal para after()? Mi awaitfunciona bien cuando lo llamo before()(elimina una entrada de DB), pero si pongo exactamente lo mismo after(), no elimina nada para cuando describe()...it()comienza un segundo y falla debido a que los datos no se eliminan.
Juha Untinen