web-dev-qa-db-fra.com

Quel est l'intérêt du rappel done ()?

Dans Mochajs, ils utilisent done() pour tester le code asynchrone, comme ceci:

describe('User', function() {
  describe('#save()', function() {
    it('should save without error', function(done) {
      var user = new User('Luna');
      user.save(function(err) {
        if (err) throw err;
        done();
      });
    });
  });
});

Qu'est-ce que cela signifie exactement? J'ai fait console.log(done.toString()) et j'ai obtenu ceci:

function (err) {
  if (err instanceof Error || toString.call(err) === '[object Error]') {
    return done(err);
  }
  if (err) {
    if (Object.prototype.toString.call(err) === '[object Object]') {
      return done(new Error('done() invoked with non-Error: '
        + JSON.stringify(err)));
    }
    return done(new Error('done() invoked with non-Error: ' + err));
  }
  done();
}

La done() à la toute fin ici est-elle différente de la done() dans le premier morceau de code?

19
PraneethVT

Mocha est capable de gérer des tests synchrones et asynchrones. Lorsque vous exécutez un test synchrone, vous pouvez simplement le passer en tant que fonction anonyme à it et vous n'avez rien d'autre à faire: Mocha sait que le test est terminé lorsque la fonction revient. Cependant, si vous exécutez un test asynchrone, vous devez indiquer à Mocha que le test est asynchrone. Il existe deux façons de procéder:

  1. Déclarez que la fonction anonyme que vous passez à it prend un paramètre. Mocha appellera votre fonction anonyme avec un seul paramètre qui est une fonction que vous devez appeler pour indiquer que votre test est terminé. (Ce paramètre est appelé done en raison de la tradition. Vous pouvez l'appeler complete, cb ou platypus et cela fonctionnerait tout de même.) Si vous appelez done sans valeur, le test est réussi. Avec une valeur, le test est un échec et la valeur doit être un objet Error ou un objet dérivé de Error.

  2. Renvoyer une promesse: Mocha attendra que la promesse soit résolue ou rejetée. S'il est résolu, le test réussit. S'il est rejeté, le test a échoué.

Le code que vous voyez lorsque vous effectuez done.toString() n'est que le code de la fonction que Mocha passe à votre test lorsque vous déclarez qu'il prend un paramètre. Vous pouvez y voir une partie de ce que j'ai mentionné ci-dessus (par exemple, si vous passez un paramètre à done il doit être un Error ou dérivé de Error). Le done dans il y a une autre fonction done qui est privée à Mocha.

18
Louis

En raison de la nature asynchrone de node.js, vous devez dire à Mocha que votre test est terminé.

Pour les langages synchrones classiques, vous avez terminé lorsque la méthode est terminée. Mais dans le noeud, tout d'abord la méthode entière est exécutée et ensuite, quelque temps après est exécutée le corps interne de user.save().

Le Mocha attend juste avec test jusqu'à ce que done(), soit appelé, car il n'a pas d'autre option pour trouver si quelque chose d'autre doit être exécuté ou s'il est terminé.

La sortie que vous avez n'est qu'un corps de fonction done.

3
libik

Tous les cas de test, y compris before (), after (), beforeEach (), afterEach () doivent appeler done () à la fin pour indiquer à mocha que toutes les tâches sont terminées.

Si done () est manquant, une exception de timeout se produira car mocha attendra "done ()" jusqu'au timeout.

3