A função assíncrona em mocha before () é sempre concluída antes de it () spec?

89

Eu tenho uma função de retorno de chamada before()que serve para limpar o banco de dados. Está tudo before()garantido para terminar antes do it()início?

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
fonte
1
Isso deve funcionar. Você só precisa ter certeza de retornar uma promessa de seu beforemanipulador. Exbefore(function () { return db.collection...}
broofa

Respostas:

125

Para novas versões de mocha:

Agora você pode devolver uma promessa ao mocha, e o mocha aguardará a conclusão antes de continuar. Por exemplo, o seguinte teste será aprovado:

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

Você pode encontrar a documentação aqui

Para versões mais antigas do mocha:

Se você deseja que sua solicitação assíncrona seja concluída antes que tudo o mais aconteça, você precisa usar o doneparâmetro em sua solicitação anterior e chamá-lo no retorno de chamada.

O Mocha irá então esperar até doneser chamado para começar a processar os blocos seguintes.

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

No entanto, você deve ter cuidado, pois não criar stub no banco de dados para teste de unidade pode retardar fortemente a execução, pois as solicitações em um banco de dados podem ser muito longas em comparação com a simples execução de código.

Para obter mais informações, consulte a documentação do Mocha .

Clément Berthou
fonte
Observe que se a operação assíncrona demorar muito, você receberá uma mensagem de falha que não é muito útil: stackoverflow.com/a/48087201/1827734
BrDaHa
Mocha agora suporta promessas em hooks - mochajs.org/#working-with-promises . Não há necessidade de usar done. Apenas devolva uma promessa.
broofa
Você também pode: before(function () { return db.collection('user').remove({}); })já que remove()retorna uma promessa, não há necessidade de embrulhá-la em umnew Promise()
Brent Greeff
7

Esperançosamente, seu db.collection () deve retornar uma promessa. Se sim, você também pode usar a palavra-chave assíncrona em 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
fonte
4
Que tal para after()? Meu awaittrabalho funciona bem quando eu o chamo before()(ele exclui uma entrada do banco de dados), mas se eu colocar exatamente a mesma coisa after(), ele não exclui nada no momento em que um segundo describe()...it()começa e falha devido aos dados não serem removidos.
Juha Untinen