Comment utiliser Hamcrest en Java pour tester une exception?
Comment puis-je utiliser Hamcrest pour tester une exception? Selon un commentaire en https://code.google.com/p/hamcrest/wiki/Tutorial, "la gestion des exceptions est fourni par Junit 4 à l'aide de l'attendu de l'attribut."
J'ai donc essayé et constaté que cela a fonctionné:
public class MyObjectifyUtilTest {
@Test
public void shouldFindFieldByName() throws MyObjectifyNoSuchFieldException {
String fieldName = "status";
String field = MyObjectifyUtil.getField(DownloadTask.class, fieldName);
assertThat(field, equalTo(fieldName));
}
@Test(expected=MyObjectifyNoSuchFieldException.class)
public void shouldThrowExceptionBecauseFieldDoesNotExist() throws MyObjectifyNoSuchFieldException {
String fieldName = "someMissingField";
String field = MyObjectifyUtil.getField(DownloadTask.class, fieldName);
assertThat(field, equalTo(fieldName));
}
}
Ne Hamcrest fournir toute fonctionnalité supplémentaire au-dessus et au-delà de la @Test(expected=...)
d'annotation à partir d'JUnit?
Alors que quelqu'un a demandé à ce sujet dans Groovy (Comment utiliser Hamcrest pour tester exception?), ma question est pour les tests unitaires écrits en Java.
Heh, bien SÛR, JUnit n'est pas encore bien établie moyen de vérifier qu'une opération spécifique jette...manque de la programmation fonctionnelle, la faute (avant Java 8, qui est)
Vous pouvez avoir un coup d'oeil à la assertj bibliothèque qui dispose d'un élégant api pour faire valoir contre exceptions: joel-costigliola.github.io/assertj/... Exemple: assertThatThrownBy(() -> { throw new Exception("boom!"); }).isInstanceOf(Exception.class);
Vous pouvez avoir un coup d'oeil à la assertj bibliothèque qui dispose d'un élégant api pour faire valoir contre exceptions: joel-costigliola.github.io/assertj/... Exemple: assertThatThrownBy(() -> { throw new Exception("boom!"); }).isInstanceOf(Exception.class);
OriginalL'auteur Michael Osofsky | 2014-12-31
Vous devez vous connecter pour publier un commentaire.
Devriez-vous vraiment besoin d'utiliser le
Hamcrest
bibliothèque?Si non, voici comment vous le faites avec
Junit
soutien d'exception pour les tests. LeExpectedException
classe a beaucoup de méthodes que vous pouvez utiliser pour faire ce que vous voulez au-delà de la vérification du type de l'jetésException
.Vous pouvez utiliser le
Hamcrest
de rapprochement en combinaison avec d'affirmer quelque chose de spécifique, mais il est préférable de laisserJunit
attendre la levée d'exceptions.Cette approche mieux que le
@Test (expected=...)
approche, car@Test (expected=...)
seulementteste si la méthode d'exécution est interrompue par jeter l'exception donnée,
pas si l'appel que vous vouliez jeter l'exception a jeté un. Par exemple, le test réussit même si
doSomething
méthode a jeté leMyObjectifyNoSuchFieldException
exception qui peut ne pas être souhaitableVous obtenez pour tester plus que juste le type de l'exception levée. Par exemple, vous pouvez vérifier une exception particulière de l'instance ou de message d'exception et ainsi de suite
La
try/catch
de l'approche modulaire, en raison de la lisibilité et de concision.il est préférable que vous obtenez pour tester la méthode exacte d'appel que vous pensez pourrait jeter une exception a jeté cette fois-ci. Le contraste que le niveau de la méthode d'annotation qui permet de ne pas vous dire la ligne qui a jeté une exception. Disons que si j'avais une ligne avant la ligne vous pensez pourrait jeter une exception donnée a jeté la même exception, votre test doit avoir effectivement échoué, mais ne serait pas avec l'annotation approche. Ce que le
@Test
annotation approche s'intéresse vraiment est la méthode de l'exécution des arrêts de jeter l'exception donnée, pas de savoir qui appeler vraiment jeté cette exception.Mise à jour de la réponse avec explication des raisons pour lesquelles cette approche est la meilleure.
Un autre avantage est que vous pouvez faire une assertion sur le message de l'exception:
exceptionGrabber.expectMessage("My expected message");
C'est passé inaperçu, ou peut-être que je suis mal interpréter quelque chose, mais vous ne voulez pas un point-virgule après que
doSomething()
appel?OriginalL'auteur mystarrocks
Je ne pouvais pas la mettre en œuvre dans une belle façon si on compte l'affirmation d'erreur de description (c'est probablement pourquoi Hamcrest ne fournit pas une telle fonctionnalité), mais si vous jouez bien avec Java 8, alors vous pourriez vouloir quelque chose comme ça (mais je ne pense pas que ce soit jamais utilisé parce que les enjeux décrits ci-dessous):
IThrowingRunnable
Cette interface est utilisée pour encapsuler du code qui pourrait lancer des exceptions.
Callable<E>
peut être aussi bien utilisé, mais celui-ci exige de retourner une valeur, donc je pense qu'un exécutable ("vide-callable") est plus pratique.FailsWithMatcher
Cette classe implémente un comparateur qui exige le rappel de lancer une exception. Un inconvénient de cette mise en œuvre est que le fait d'avoir un rappel de lancer une exception inattendue (ou même de ne pas jeter un seul) ne décrit pas ce qui est erroné et que vous souhaitez voir totalement obscur des messages d'erreur.
ExceptionMessageMatcher
Ceci est un exemple de la correspondance de faire une simple vérification pour la levée d'une exception message.
Et le test de l'échantillon lui-même
Noter que cette approche:
Et le pire, c', typique de l'échec ressemblera
Peut-être en utilisant une mesure de mise en œuvre de la
assertThat()
méthode pourrait résoudre.Nice. Si la "mais: a ..." message à afficher la levée d'une exception, je serais très heureux avec cela. Mais malheureusement, je ne vois pas le moyen de le faire sans faire de stocker de l'état dans le matcher, ou en appelant le lambda deux fois, ce qui arrivait souvent de créer un résultat différent. 🙁
OriginalL'auteur Lyubomyr Shaydariv
En plus de ci-dessus.
si vous modifiez les interfaces de ... s'étend Exception, vous pouvez jeter une Erreur comme ceci:
trace ressemblera à ceci:
OriginalL'auteur Wolf
Je suppose que la façon la plus propre est de définir une fonction comme
quelque part et puis par exemple, appeler
peut-être aussi à l'aide de quelque chose comme la ExceptionMessageMatcher de cette réponse.
OriginalL'auteur Hans-Peter Störr