Meilleure façon de tester les exceptions avec Assert pour vous assurer qu’elles seront lancées

Pensez-vous que c’est un bon moyen de tester les exceptions? Aucune suggestion?

Exception exception = null; try{ //I m sure that an exeption will happen here } catch (Exception ex){ exception = ex; } Assert.IsNotNull(exception); 

J’utilise MS Test.

J’ai quelques modèles différents que j’utilise. J’utilise l’atsortingbut ExpectedException plupart du temps lorsqu’une exception est attendue. Cela suffit dans la plupart des cas, cependant, dans certains cas, cela ne suffit pas. L’exception peut ne pas être capturable – car elle est lancée par une méthode appelée par reflection – ou je veux simplement vérifier que d’autres conditions sont remplies, qu’une transaction est annulée ou qu’une valeur a encore été définie. Dans ces cas, je l’enveloppe dans un bloc try/catch qui attend l’exception exacte, effectue un Assert.Fail si le code réussit et Assert.Fail également les exceptions génériques pour s’assurer qu’une exception différente n’est pas levée.

Premier cas:

 [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void MethodTest() { var obj = new ClassRequiringNonNullParameter( null ); } 

Deuxième cas:

 [TestMethod] public void MethodTest() { try { var obj = new ClassRequiringNonNullParameter( null ); Assert.Fail("An exception should have been thrown"); } catch (ArgumentNullException ae) { Assert.AreEqual( "Parameter cannot be null or empty.", ae.Message ); } catch (Exception e) { Assert.Fail( ssortingng.Format( "Unexpected exception of type {0} caught: {1}", e.GetType(), e.Message ) ); } } 

Je suis nouveau ici et je n’ai pas la réputation de commenter ou de voter, mais je voulais signaler un défaut dans l’exemple de la réponse d’Andy White :

 try { SomethingThatCausesAnException(); Assert.Fail("Should have exceptioned above!"); } catch (Exception ex) { // whatever logging code } 

Dans tous les frameworks de tests unitaires que je connais, Assert.Fail fonctionne en lançant une exception, de sorte que la capture générique masque en fait l’échec du test. Si SomethingThatCausesAnException() Assert.Fail SomethingThatCausesAnException() ne lance pas, Assert.Fail fera, mais cela ne se produira jamais pour indiquer un échec.

Si vous devez intercepter l’exception attendue (c’est-à-dire, pour affirmer certains détails, comme le message / les propriétés de l’exception), il est important d’attraper le type attendu spécifique, et non la classe Exception de base. Cela permettrait à l’exception Assert.Fail d’échapper (en supposant que vous ne lancez pas le même type d’exception que votre environnement de test unitaire), tout en autorisant la validation de l’exception lancée par votre méthode SomethingThatCausesAnException() .

Maintenant, en 2017, vous pouvez le faire plus facilement avec le nouveau framework MSTest V2 :

 Assert.ThrowsException(() => myClass.MyMethodWithError()); 

A partir de la version 2.5, NUnit a le niveau de méthode suivant Assert s pour tester les exceptions:

Assert.Throws , qui testera un type d’exception exact:

 Assert.Throws(() => someNullObject.ToSsortingng()); 

Et Assert.Catch , qui testera une exception d’un type donné ou un type d’exception dérivé de ce type:

 Assert.Catch(() => someNullObject.ToSsortingng()); 

En passant, lorsque vous déboguez des tests unitaires qui génèrent des exceptions, vous pouvez empêcher les VS de casser l’exception .

modifier

Pour donner un exemple du commentaire de Matthew ci-dessous, le retour des Assert.Throws et Assert.Catch génériques est l’exception avec le type de l’exception, que vous pouvez ensuite examiner pour une inspection ultérieure:

 // The type of ex is that of the generic type parameter (SqlException) var ex = Assert.Throws(() => MethodWhichDeadlocks()); Assert.AreEqual(1205, ex.Number);