44 votes

Est-ce contraire aux bonnes pratiques de lancer une exception dans la plupart des tests JUnit ?

Presque tous mes tests JUnit sont écrits avec la signature suivante :

public void testSomething() throws Exception

Mon raisonnement est que je peux me concentrer sur ce que je teste plutôt que sur la gestion des exceptions que JUnit semble me fournir gratuitement. Mais est-ce que je rate quelque chose en faisant cela ? Cela va-t-il à l'encontre des meilleures pratiques ? Est-ce que je gagnerais quelque chose en attrapant explicitement des exceptions spécifiques dans mon test et en échouant () sur celles-ci ?

55voto

Ophidian Points 3431

En général, si vous testez un cas où vous ne vous attendez pas à ce qu'une exception se produise, alors je laisserais la méthode de test lancer l'exception comme vous l'avez illustré, car cela permettra de différencier clairement les cas suivants Échec les cas de test (ils ne passent pas une de vos assertions) et Erreur les cas de test (ils provoquent une exception inattendue). Les TestRunners de JUnit rattraperont l'exception générée, de sorte que vous n'avez pas à vous inquiéter de voir toute votre suite de tests s'interrompre si une exception est générée.

D'un autre côté, si vous écrivez un test qui est censé déclencher une exception, alors vous voulez soit utiliser la fonction @Test(expected=IllegalArgumentException.class) de l'annotation JUnit 4, ou de l'idiome JUnit 3, plus courant, de :

try {
  target.someMethodToTest();
  fail("Should have gotten an exception");
} catch (IllegalStateException ise) {
  //expected, it's all good
}

11voto

Kevin Bourrillion Points 19677

N'attrapez PAS et échouez - vous perdrez des informations précieuses. Laissez toutes les exceptions s'envoler. Cela signifie que vous devez ajouter à votre signature chaque exception vérifiée qui peut être lancée. Cependant, je vous conseille de ne pas prendre la voie de la paresse et d'utiliser aveuglément les méthodes suivantes throws Exception par habitude. Cela vous dispense de ne jamais avoir à pensez à sur la façon dont votre API se comporte réellement en matière d'exceptions.

3voto

jayshao Points 1608

Le principal avantage est que vous testez un scénario qui nécessite la levée d'une exception (par exemple, la gestion des erreurs).

Vous pouvez dans JUnit4 utiliser quelque chose comme : @Test(expected=ArithmeticException.class) mais certaines personnes trouvent que c'est plus difficile à lire/moins révélateur d'intention qu'un bloc explicite try{} catch (Exception e), et si vous voulez vérifier l'état (par exemple d'un objet fantaisie, ou voir si l'exception a été levée au bon endroit, ou enregistrée, etc.)

3voto

duffymo Points 188155

Si une exception est levée et que vous ne vous y attendez pas, le test doit échouer.

S'il s'agit d'une exception non vérifiée, j'autorise l'exception à être levée et JUnit fait échouer le test.

S'il s'agit d'une exception vérifiée, vous avez le choix : soit ajouter l'exception à la clause throws de la signature de la méthode, soit l'attraper à l'intérieur de la méthode. Le compilateur vous impose un choix, car vous ne pouvez pas exécuter le code sans l'un ou l'autre de ces choix.

Ces derniers temps, j'ai eu tendance à ne pas attraper les exceptions dans mes tests. S'il est supposé lancer une exception, je le marque comme tel avec l'annotation. Si elle lève une exception non vérifiée, je laisse JUnit échouer le test pour moi. Si c'est une exception vérifiée, j'ajoute la clause throws à la signature de la méthode et je laisse JUnit échouer le test pour moi.

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