Comment utiliser
Assert
(ou une autre classe de test?) Pour vérifier qu'une exception a été levée?
830
Comment utiliser
Assert
(ou une autre classe de test?) Pour vérifier qu'une exception a été levée?
Réponses:
Pour "Visual Studio Team Test", il apparaît que vous appliquez l'attribut ExpectedException à la méthode du test.
Exemple de documentation ici: Procédure pas à pas de test unitaire avec Visual Studio Team Test
la source
Habituellement, votre framework de test aura une réponse à cela. Mais si ce n'est pas assez flexible, vous pouvez toujours le faire:
Comme le souligne @Jonas, cela ne fonctionne PAS pour intercepter une exception de base:
Si vous devez absolument attraper Exception, vous devez relancer Assert.Fail (). Mais vraiment, c'est un signe que vous ne devriez pas écrire cela à la main; vérifiez votre framework de test pour les options, ou voyez si vous pouvez lever une exception plus significative à tester.
Vous devriez être en mesure d'adapter cette approche à tout ce que vous voulez, notamment en spécifiant les types d'exceptions à intercepter. Si vous ne vous attendez qu'à certains types, terminez les
catch
blocs avec:la source
Ma méthode préférée pour implémenter cela est d'écrire une méthode appelée Throws et de l'utiliser comme n'importe quelle autre méthode Assert. Malheureusement, .NET ne vous permet pas d'écrire une méthode d'extension statique, vous ne pouvez donc pas utiliser cette méthode comme si elle appartenait réellement à la génération dans la classe Assert; faites simplement un autre appelé MyAssert ou quelque chose de similaire. La classe ressemble à ceci:
Cela signifie que votre test unitaire ressemble à ceci:
Qui ressemble et se comporte beaucoup plus comme le reste de vos syntaxes de test unitaire.
la source
Assert.ThrowsException<T>
etAssert.ThrowsExceptionAsync<T>
- voir blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/…si vous utilisez NUNIT, vous pouvez faire quelque chose comme ceci:
Il est également possible de stocker l'exception levée afin de la valider davantage:
Voir: http://nunit.org/docs/2.5/exceptionAsserts.html
la source
Si vous utilisez MSTest, qui à l'origine n'avait pas d'
ExpectedException
attribut, vous pouvez le faire:la source
Méfiez-vous de l'utilisation d'ExpectedException, car cela peut entraîner plusieurs pièges, comme illustré 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 tester les exceptions, il existe moins de moyens désapprouvés. Vous pouvez utiliser la méthode try {act / fail} catch {assert}, qui peut être utile pour les frameworks qui ne prennent pas directement en charge les tests d'exception autres que ExpectedException.
Une meilleure alternative consiste à utiliser xUnit.NET, qui est un cadre de test unitaire très moderne, prospectif et extensible qui a appris de toutes les autres erreurs et s'est amélioré. Une telle amélioration est Assert.Throws, qui fournit une bien meilleure syntaxe pour affirmer des exceptions.
Vous pouvez trouver xUnit.NET sur github: http://xunit.github.io/
la source
MSTest (v2) a maintenant une fonction Assert.ThrowsException qui peut être utilisée comme ceci:
Vous pouvez l'installer avec nuget:
Install-Package MSTest.TestFramework
la source
Dans un projet sur lequel je travaille, nous avons une autre solution pour cela.
Tout d'abord, je n'aime pas le ExpectedExceptionAttribute car il prend en considération l'appel de méthode qui a provoqué l'exception.
Je fais cela avec une méthode d'aide à la place.
Tester
HelperMethod
Neat, n'est-ce pas;)
la source
C'est un attribut de la méthode de test ... vous n'utilisez pas Assert. Ressemble à ça:
la source
Vous pouvez télécharger un package à partir de Nuget à l'aide de: PM> Install-Package MSTestExtensions qui ajoute la syntaxe Assert.Throws () dans le style nUnit / xUnit à MsTest.
Instructions de haut niveau: téléchargez l'assembly et héritez de BaseTest et vous pouvez utiliser la syntaxe Assert.Throws () .
La méthode principale pour l'implémentation de Throws se présente comme suit:
Divulgation: J'ai mis en place ce package.
Plus d'informations: http://www.bradoncode.com/blog/2012/01/asserting-exceptions-in-mstest-with.html
la source
Vous pouvez y parvenir avec une simple ligne.
Si votre opération
foo.bar()
est asynchrone:Si
foo.bar()
n'est pas asynchronela source
ArgumentException
par exemple. L'ancien Try Catch et test de la réponse d'exception est toujours préféré si vous avez des critères avancés à tester, mais pour beaucoup de mes cas, cela aide beaucoup!Je ne recommande pas d'utiliser l'attribut ExpectedException (car il est trop contraignant et sujet aux erreurs) ou d'écrire un bloc try / catch dans chaque test (car il est trop compliqué et sujet aux erreurs). Utilisez une méthode d'assertion bien conçue - fournie par votre framework de test ou écrivez la vôtre. Voici ce que j'ai écrit et utilisé.
Exemple utilise:
REMARQUES
Renvoyer l'exception au lieu de prendre en charge un rappel de validation est une idée raisonnable, sauf que cela rend la syntaxe d'appel de cette assertion très différente de celle des autres assertions que j'utilise.
Contrairement à d'autres, j'utilise «propage» au lieu de «lancers» car nous ne pouvons tester que 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 dire que les lancers d'images sont: lancés et non attrapés.
PENSÉE FINALE
Avant de passer à ce type d'approche, j'ai envisagé d'utiliser l'attribut ExpectedException lorsqu'un test ne vérifiait que le type d'exception et d'utiliser un bloc try / catch si une validation supplémentaire était requise. Mais, non seulement je devrais réfléchir à la technique à utiliser pour chaque test, mais changer le code d'une technique à l'autre en fonction des besoins n'était pas un effort trivial. L'utilisation d'une approche cohérente économise l'effort mental.
Donc en résumé, cette approche sportive: facilité d'utilisation, flexibilité et robustesse (difficile de se tromper).
la source
L'assistant fourni par @Richiban ci-dessus fonctionne très bien, sauf qu'il ne gère pas la situation où une exception est levée, mais pas le type attendu. Les réponses suivantes:
la source
Puisque vous mentionnez l'utilisation d'autres classes de test, une meilleure option que l'
ExpectedException
attribut est d'utiliser Shoudly 's Should.Throw .Disons que nous avons une exigence que le client doit avoir une adresse pour créer une commande . Sinon, la
CreateOrderForCustomer
méthode devrait aboutir à unArgumentException
. Ensuite, nous pourrions écrire:C'est mieux que d'utiliser un
ExpectedException
attribut, car nous sommes précis sur ce qui devrait déclencher l'erreur. Cela rend les exigences de nos tests plus claires et facilite également le diagnostic lorsque le test échoue.Notez qu'il existe également un
Should.ThrowAsync
test de méthode asynchrone.la source
Comme alternative, vous pouvez essayer de tester les exceptions qui sont en fait lancées avec les 2 lignes suivantes de votre test.
la source
Dans les tests unitaires intégrés VS si vous voulez simplement vérifier que "toute exception" est levée, mais que vous ne connaissez pas le type, vous pouvez utiliser un catch all:
la source
Eh bien, je vais résumer à peu près ce que tout le monde ici a dit avant ... Quoi qu'il en soit, voici le code que j'ai construit en fonction des bonnes réponses :) Tout ce qu'il reste à faire est de copier et d'utiliser ...
la source
Consultez nUnit Docs pour des exemples sur:
la source
Cela dépendra du cadre de test que vous utilisez?
Dans MbUnit, par exemple, vous pouvez spécifier l'exception attendue avec un attribut pour vous assurer d'obtenir l'exception que vous attendez vraiment.
la source
En cas d'utilisation de NUnit , essayez ceci:
la source
Il existe une bibliothèque géniale appelée NFluent qui accélère et facilite la façon dont vous écrivez vos assertions .
Il est assez simple d'écrire une assertion pour lever une exception:
la source
Même s'il s'agit d'une vieille question, je voudrais ajouter une nouvelle réflexion à la discussion. J'ai étendu le modèle Arrange, Act, Assert à prévoir, Arrange, Act, Assert. Vous pouvez créer un pointeur d'exception attendu, puis affirmer qu'il a été affecté à. Cela semble plus propre que de faire vos Asserts dans un bloc catch, laissant votre section Act principalement juste pour la seule ligne de code pour appeler la méthode en cours de test. Vous n'avez pas non plus à aller
Assert.Fail();
ou àreturn
partir de plusieurs points dans le code. Toute autre exception levée entraînera l'échec du test, car il ne sera pas intercepté, et si une exception de votre type attendu est levée, mais ce n'était pas celle que vous attendiez, Asserting contre le message ou d'autres propriétés de l'exception permet de vous assurer que votre test ne passera pas par inadvertance.la source