81 votes

Existe-t-il un moyen de faire fonctionner Chai avec les tests asynchrones Mocha?

Je suis de l'exécution de certains tests asynchrones à Moka en utilisant le Navigateur de Coureur et je suis en train d'utiliser Chai attendent style assertions:

window.expect = chai.expect;
describe('my test', function() {
  it('should do something', function (done) {
    setTimeout(function () {
      expect(true).to.equal(false);
    }, 100);
  }
}

Cela ne veut pas me donner la normale échec d'assertion message, au lieu-je obtenir:

Error: the string "Uncaught AssertionError: expected true to equal false" was thrown, throw an Error :)
    at Runner.fail (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3475:11)
    at Runner.uncaught (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3748:8)
    at uncaught (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3778:10)

Donc, c'est évidemment la capture de l'erreur, c'est juste de ne pas l'afficher correctement. Aucune idées de comment faire cela? Je suppose que je pourrais appeler juste "fait" une erreur de l'objet, mais alors je perds toute l'élégance de quelque chose comme Chai et il devient très maladroit...

97voto

Jean Vincent Points 3136

Votre asynchrone test génère une exception, sur échec d'attendre()ation, qui ne peuvent être saisis par elle (), car l'exception est levée, en dehors d'elle()'s portée.

La capture d'exception que vous voyez affiché est capturé à l'aide de processus.sur( 'uncaughtException' ) en vertu de nœud ou de l'utilisation de la fenêtre.onerror dans le navigateur.

Pour résoudre ce problème, vous avez besoin pour capturer l'exception au sein de l'asynchrone fonction appelée par setTimeout() pour appeler done() à l'exception que le premier paramètre. Vous devez également appeler done() sans paramètre pour indiquer la réussite, sinon moka ferait rapport une erreur de dépassement de délai parce que votre fonction de test n'aurait jamais signalé qu'il a été fait():

window.expect = chai.expect;
describe('my test', function() {
  it( 'should do something', function (done) {
    // done() is provided by it() to indicate asynchronous completion
    // call done() with no parameter to indicate that it() is done() and successful
    // or with an error to indicate that it() failed
    setTimeout( function () {
      // Called from the event loop, not it()
      // So only the event loop could capture uncaught exceptions from here
      try {
        expect( true ).to.equal( false );
        done()    // success: call done with no parameter to indicate that it() is done()
      } catch( e ) {
        done( e ) // failure: call done with an error Object to indicate that it() failed
      }
    }, 100 );
    // returns immediately after setting timeout
    // so it() can no longer catch exception happening asynchronously
  }
}

Le faire sur tous vos cas de test est ennuyeux et pas SEC, alors vous voudrez peut-être fournir une fonction pour le faire pour vous. Nous allons appeler cette fonction check():

function check( done, f ) {
  try {
    f()
    done()
  } catch( e ) {
    done( e )
  }
}

Avec check() vous pouvez maintenant réécrire votre asynchrone tests comme suit:

window.expect = chai.expect;
describe('my test', function() {
  it( 'should do something', function (done) {
    setTimeout( function () {
      check( done, function() {
        expect(true).to.equal(false);
      } )
    }, 100);
  }
}

13voto

xinthink Points 173

Si vous aimez promis, essayez Chai comme Promised + Q , qui permet quelque chose comme ceci:

 doSomethingAsync().should.eventually.equal("foo").notify(done);
 

2voto

DjebbZ Points 535

J'ai demandé la même chose dans le Moka liste de diffusion. En gros, ils m'ont dit ceci : écrire asynchrone test avec Moka et de Chai :

  • toujours commencer le test avec if (err) done(err);
  • toujours à la fin de l'essai avec done().

Il a résolu mon problème, et ne pas changer une seule ligne de mon code dans l'entre-deux (Chai attentes parmi d'autres). L' setTimout n'est pas la façon de le faire async tests.

Voici le lien vers la discussion sur la liste de diffusion.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X