543 votes

Comment écrire un test qui attend une erreur levée

Je suis en train d'écrire un test pour le Jasmin Framework de Test qui s'attend à une erreur. Pour le moment je suis en utilisant un jasmin nodejs intégration à partir de github.

Dans mon module nodejs j'ai le code suivant:

throw new Error("Parsing is not possible");

Maintenant, j'essaie d'écrire un test qui attend cette erreur:

describe('my suite...', function() {
    [..]
    it('should not parse foo', function() {
    [..]
        expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));
    });
});

J'ai essayé aussi Error() et certains autres variantes et ne peuvent tout simplement pas comprendre comment le faire fonctionner.

Voici le code du jasmin lib, où toThrow est défini:

jasmine.Matchers.prototype.toThrow = function(expected) {
  var result = false;
  var exception;
  if (typeof this.actual != 'function') {
    throw new Error('Actual is not a function');
  }
  try {
    this.actual();
  } catch (e) {
    exception = e;
  }
  if (exception) {
    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
  }

  var not = this.isNot ? "not " : "";

  this.message = function() {
    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
      return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' ');
    } else {
      return "Expected function to throw an exception.";
    }
  };

  return result;
};

886voto

Pete Hodgson Points 5147

vous devriez être en passant une fonction dans le `` appeler. Le code que vous avez ici :

essaie en fait appelerpour tenter de passer le résultat dans ,

Essayez d’utiliser une fonction anonyme à la place :

78voto

Andrzej Śliwa Points 660

Vous utilisez:

expect(fn).toThrow(e)

Mais si vous avez un coup d'oeil sur la fonction commentaire (attendu est une chaîne):

294 /**
295  * Matcher that checks that the expected exception was thrown by the actual.
296  *
297  * @param {String} expected
298  */
299 jasmine.Matchers.prototype.toThrow = function(expected) {

Je suppose que vous devez probablement l'écrire comme ceci (à l'aide de la lambda - fonction anonyme):

expect(function() { parser.parse(raw); } ).toThrow("Parsing is not possible");

Ceci est confirmé dans l'exemple suivant:

expect(function () {throw new Error("Parsing is not possible")}).toThrow("Parsing is not possible");

Douglas Crockford recommande fortement cette approche, au lieu d'utiliser "throw new Error()" (prototypage):

throw {
   name: "Error",
   message: "Parsing is not possible"
}

24voto

Jake Points 763

- Je remplacer le Jasmin est toThrow matcher avec le suivant, qui vous permet de correspondre à l'exception du nom de la propriété ou de son message à la propriété. Pour moi, cela fait des tests plus faciles à écrire et moins cassants, que je peux faire ce qui suit:

throw {
   name: "NoActionProvided",
   message: "Please specify an 'action' property when configuring the action map."
}

et puis test avec les éléments suivants:

expect (function () {
   .. do something
}).toThrow ("NoActionProvided");

Cela me permet d'ajuster le message de l'exception plus tard sans casser des tests, lorsque la chose importante est qu'il a jeté le type attendu de l'exception.

C'est le remplacement de toThrow qui permet cela:

jasmine.Matchers.prototype.toThrow = function(expected) {
  var result = false;
  var exception;
  if (typeof this.actual != 'function') {
    throw new Error('Actual is not a function');
  }
  try {
    this.actual();
  } catch (e) {
    exception = e;
  }
  if (exception) {
      result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected) || this.env.equals_(exception.name, expected));
  }

  var not = this.isNot ? "not " : "";

  this.message = function() {
    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
      return ["Expected function " + not + "to throw", expected ? expected.name || expected.message || expected : " an exception", ", but it threw", exception.name || exception.message || exception].join(' ');
    } else {
      return "Expected function to throw an exception.";
    }
  };

  return result;
};

12voto

tolbard Points 310

Je sais que c’est plus de code, mais vous pouvez également faire :

6voto

fernandohur Points 899

Pour les amateurs de coffeescript

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