Comment puis-je utiliser Assert pour vérifier qu'une exception a été levée?
Comment puis-je utiliser Assert (ou autre classe de Test?) pour vérifier qu'une exception a été levée?
- Qui framework de test unitaire utilisez-vous?
- Intégré De Visual Studio
- Ne pas ExpectedException attribut de l'aide? ref: msdn.microsoft.com/en-us/library/...
- Marrant, je viens de terminer la recherche de la réponse à ceci, trouvé sur stackoverflow.com/questions/741029/testing-exceptions.
- Voir aussi: stackoverflow.com/questions/741029/...
- Double Possible de le Meilleur moyen de tester les exceptions à faire Valoir pour s'assurer qu'ils seront jetés
Vous devez vous connecter pour publier un commentaire.
Pour "Visual Studio Team Test" il semble que vous appliquez le ExpectedException attribut à l'épreuve de la méthode.
De l'échantillon à partir de la documentation ici: Un Test Unitaire Procédure pas à pas avec Visual Studio Team Test
Généralement votre framework de tests aurez une réponse pour cela. Mais si elle n'est pas assez souple, vous pouvez toujours le faire:
Comme @Jonas fait remarquer, cela NE fonctionne PAS pour la capture d'une base d'Exception:
Si vous devez absolument Exception de catch, vous devez renvoyer l'Affirmer.Fail(). Mais vraiment, c'est un signe que vous ne devriez pas être à la main l'écriture de ce; vérifier votre framework de test pour les options, ou voir si vous pouvez jeter un plus significatif exception à tester.
Vous devriez être en mesure d'adapter cette approche à ce que vous voulez -- y compris la spécification de ce type d'exceptions à attraper. Si vous attendre seulement à certains types de terminer la
catch
blocs avec:Ma méthode de prédilection pour la mise en œuvre de ce qui est d'écrire une méthode appelée Jette, et l'utiliser comme tout autre méthode Assert. Malheureusement, .NET ne vous autorise pas à écrire un statique de la méthode d'extension, de sorte que vous ne pouvez pas utiliser cette méthode que si elle appartient à la classe Assert, il suffit de prendre un autre appelé MyAssert ou quelque chose de similaire. La classe ressemble à ceci:
Qui signifie que votre unité de test ressemble à ceci:
Qui ressemble et se comporte beaucoup plus comme le reste de votre unité de test de syntaxes.
Assert.ThrowsException<T>
etAssert.ThrowsExceptionAsync<T>
- voir blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/...Si vous êtes à l'aide de MSTest, qui à l'origine n'avait pas de
ExpectedException
attribut, vous pourriez faire ceci:si vous utilisez NUNIT, vous pouvez faire quelque chose comme ceci:
Il est également possible de stocker la levée d'une exception afin de valider encore plus loin:
Voir: http://nunit.org/docs/2.5/exceptionAsserts.html
Méfiez-vous de l'utilisation de ExpectedException, car il peut conduire à plusieurs difficultés, comme l'ont démontré ici:
http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx
Et ici:
http://xunit.github.io/docs/comparisons.html
Si vous avez besoin de test pour les exceptions, il y a moins de froncer les sourcils sur les moyens. Vous pouvez utiliser le try{loi/fail}catch{assert} méthode, qui peut être utile pour les cadres qui n'ont pas de support direct de l'exception tests autres que ExpectedException.
Une meilleure alternative est d'utiliser xUnit.NET qui est très moderne, tourné vers l'avenir, et extensible framework de test unitaire qui a appris de toutes les autres erreurs, et de l'améliorer. Une de ces améliorations est faire Valoir.Jette, qui offre une bien meilleure syntaxe pour faire valoir des exceptions.
Vous pouvez trouver xUnit.NET sur github: http://xunit.github.io/
Dans un projet, je travaille sur, nous avons une autre solution en faisant cela.
D'abord je n'aime pas la ExpectedExceptionAttribute, car il ne prend en considération que l'appel de la méthode qui a provoqué l'Exception.
Je le fais avec un helpermethod à la place.
Test
HelperMethod
Soigné, n'est-il pas;)
MSTest (v2) a maintenant une Assertion.ThrowsException fonction qui peut être utilisée comme ceci:
Vous pouvez l'installer avec nuget:
Install-Package MSTest.TestFramework
C'est un attribut sur la méthode d'essai... vous n'utilisez pas l'Affirmer. Ressemble à ceci:
Vous pouvez télécharger un paquet de Nuget à l'aide de: H> Install-Package MSTestExtensions qui ajoute Affirmer.Jette() syntaxe dans le style de nUnit/xUnit à MsTest.
De haut niveau instructions: télécharger l'assemblée et hériter de BaseTest et vous pouvez utiliser le Affirmer.Jette() syntaxe.
La principale méthode pour les Lancers de mise en œuvre se présente comme suit:
Divulgation: j'ai mis en place ce package.
Plus D'Infos: http://www.bradoncode.com/blog/2012/01/asserting-exceptions-in-mstest-with.html
Vous pouvez réaliser cela avec un simple en-ligne.
Si votre opération
foo.bar()
est asynchrone:Si
foo.bar()
n'est pas asynchroneArgumentException
par exemple. La vieille Essayer de les Attraper et de tester l'exception de la réponse est toujours préférable si vous avez des critères avancés pour tester, mais pour beaucoup de mes cas, cela aide beaucoup!Je ne recommandons pas l'utilisation de la ExpectedException attribut (car il est trop contraignant et source d'erreurs) ou d'écrire un bloc try/catch pour chaque test (comme c'est trop compliqué et source d'erreurs). Utilisez un bien-conçu méthode assert -- soit fourni par votre framework de test ou écrire votre propre. Voici ce que j'ai écrit et de l'utilisation.
Exemple d'utilisation:
NOTES
Retour de l'exception au lieu de soutenir une validation de rappel est une idée raisonnable, sauf que cela rend la syntaxe d'appel de cette assertion très différent de celui des autres affirme-je utiliser.
Contrairement à d'autres, j'utilise "propage" au lieu de "lance" puisque nous ne pouvons tester si une exception se propage à partir d'un appel. Nous ne pouvons pas tester directement qu'une exception est levée. Mais je suppose que vous pourriez l'image lève pour dire: jeté et n'est pas pris.
DERNIÈRE PENSÉE
Avant de passer à ce genre d'approche que j'ai considéré en utilisant le ExpectedException attribut lorsqu'un test seulement vérifié le type d'exception et à l'aide d'un bloc try/catch si plus de la validation est nécessaire. Mais, non seulement je dois penser à la technique à utiliser pour chaque test, mais de modifier le code d'une technique à l'autre à mesure que les besoins changé n'était pas trivial effort. En utilisant une approche cohérente de la sauve de l'effort mental.
Donc en résumé, cette approche sports: facilité d'utilisation, la flexibilité et la robustesse (dur de faire mal).
L'aide fournie par @Richiban ci-dessus fonctionne très bien sauf qu'il ne gère pas le cas où une exception est levée, mais pas du type attendu. Les adresses suivantes que:
Puisque vous parlez de l'utilisation d'autres classes de test, une meilleure option que la
ExpectedException
attribut est d'utiliser Shoudly's Le devrait.Jeter.Disons que nous avons une obligation de l' client doit avoir un adresse pour créer un ordre. Si pas, le
CreateOrderForCustomer
méthode qui devrait aboutir à unArgumentException
. Ensuite, nous pourrions écrire:C'est mieux que d'utiliser un
ExpectedException
attribut parce que nous sommes d'être précis sur ce que doit jeter l'erreur. Cela rend les exigences lors de nos tests, plus claire et aussi rend le diagnostic plus facile lorsque le test échoue.Notez qu'il existe également un
Should.ThrowAsync
asynchrone de la méthode de test.Comme alternative, vous pouvez essayer de tester les exceptions sont, en fait, être jetés avec les 2 lignes de votre test.
Eh bien, je vais assez bien résumer ce que tout le monde ici l'a dit avant...de toute façon, voici le code que j'ai construit selon les bonnes réponses 🙂 Tout reste à faire est de copier et d'utiliser...
VS intégré dans l'unité de test si vous voulez tout simplement pour vérifier que "tout" l'exception est levée, mais vous ne connaissez pas le type, vous pouvez utiliser un fourre-tout:
Découvrez nUnit Docs pour des exemples:
Cela va dépendre de ce framework de test que vous utilisez?
Dans MbUnit, par exemple, vous pouvez spécifier l'exception prévue avec un attribut pour s'assurer que vous obtenez l'exception que vous attendez vraiment.
Dans le cas de l'utilisation NUnit, essayez ceci:
Il est génial appelé bibliothèque NFluent qui accélère et facilite la façon dont vous écrivez vos affirmations.
Il est assez simple d'écrire une affirmation pour lancer une exception:
Même si c'est une vieille question, je voudrais ajouter une nouvelle pensée de la discussion. J'ai étendu l'Organiser, d'Agir, de faire Valoir de motif à prévoir, Organiser, d'Agir, de faire Valoir. Vous pouvez faire une exception prévue pointeur, puis affirmer qu'il a été attribué. C'est plus propre que de faire votre Affirme dans un bloc catch, en laissant votre article de la Loi sur la plupart uniquement pour une seule ligne de code pour appeler la méthode en cours de test. Vous aussi vous n'avez pas à
Assert.Fail();
oureturn
à partir de plusieurs points dans le code. Toute autre exception levée va provoquer le test à l'échec, car il ne sera pas dans le piège, et si une exception de votre type attendu est levée, mais elle n'était pas celle que vous attendiez, faire Valoir à l'encontre du message ou d'autres propriétés de l'exception de l'aide assurez-vous que votre test ne passera pas par inadvertance.