Comment utiliser Assert.Throws
pour affirmer le type de l'exception et la formulation du message.
Quelque chose comme ça:
Assert.Throws<Exception>(
()=>user.MakeUserActive()).WithMessage("Actual exception message")
La méthode que je teste envoie plusieurs messages du même type, avec des messages différents, et j'ai besoin d'un moyen de vérifier que le message correct est envoyé en fonction du contexte.
Assert.Throws
renvoie l'exception levée qui vous permet d'affirmer l'existence de l'exception.
var ex = Assert.Throws<Exception>(() => user.MakeUserActive());
Assert.That(ex.Message, Is.EqualTo("Actual exception message"));
Ainsi, si aucune exception n'est levée ou si une exception du type incorrect est levée, la première assertion Assert.Throws
échouera. Cependant, si une exception du type correct est levée, vous pouvez maintenant affirmer sur l'exception réelle que vous avez enregistrée dans la variable.
En utilisant ce modèle, vous pouvez affirmer autre chose que le message d'exception, par exemple: dans le cas de ArgumentException
et de ses dérivés, vous pouvez affirmer que le nom du paramètre est correct:
var ex = Assert.Throws<ArgumentNullException>(() => foo.Bar(null));
Assert.That(ex.ParamName, Is.EqualTo("bar"));
Vous pouvez également utiliser l'API fluide pour effectuer ces assertions:
Assert.That(() => foo.Bar(null),
Throws.Exception
.TypeOf<ArgumentNullException>()
.With.Property("ParamName")
.EqualTo("bar"));
Un petit conseil lors de l’affirmation de messages d’exception consiste à décorer la méthode de test avec SetCultureAttribute
pour s’assurer que le message émis utilise la culture attendue. Cela entre en jeu si vous stockez vos messages d'exception sous forme de ressources pour permettre la localisation.
Vous pouvez maintenant utiliser les attributs ExpectedException
, par exemple.
[Test]
[ExpectedException(typeof(InvalidOperationException),
ExpectedMessage="You can't do that!"]
public void MethodA_WithNull_ThrowsInvalidOperationException()
{
MethodA(null);
}
Assert.That(myTestDelegate, Throws.ArgumentException
.With.Property("Message").EqualTo("your argument is invalid."));
C'est une question ancienne mais pertinente avec des réponses obsolètes alors j'ajoute la solution actuelle:
public void Test() {
throw new MyCustomException("You can't do that!");
}
[TestMethod]
public void ThisWillPassIfExceptionThrown()
{
var exception = Assert.ThrowsException<MyCustomException>(
() => Test(),
"This should have thrown!");
Assert.AreEqual("You can't do that!", exception.Message);
}
Cela fonctionne avec using Microsoft.VisualStudio.TestTools.UnitTesting;
Pour développer la réponse de persistent, et pour fournir davantage de fonctionnalités de NUnit, vous pouvez procéder comme suit:
public bool AssertThrows<TException>(
Action action,
Func<TException, bool> exceptionCondition = null)
where TException : Exception
{
try
{
action();
}
catch (TException ex)
{
if (exceptionCondition != null)
{
return exceptionCondition(ex);
}
return true;
}
catch
{
return false;
}
return false;
}
Exemples:
// No exception thrown - test fails.
Assert.IsTrue(
AssertThrows<InvalidOperationException>(
() => {}));
// Wrong exception thrown - test fails.
Assert.IsTrue(
AssertThrows<InvalidOperationException>(
() => { throw new ApplicationException(); }));
// Correct exception thrown - test passes.
Assert.IsTrue(
AssertThrows<InvalidOperationException>(
() => { throw new InvalidOperationException(); }));
// Correct exception thrown, but wrong message - test fails.
Assert.IsTrue(
AssertThrows<InvalidOperationException>(
() => { throw new InvalidOperationException("ABCD"); },
ex => ex.Message == "1234"));
// Correct exception thrown, with correct message - test passes.
Assert.IsTrue(
AssertThrows<InvalidOperationException>(
() => { throw new InvalidOperationException("1234"); },
ex => ex.Message == "1234"));
Je me rends bien compte que cette question a été soulevée depuis longtemps, mais je me suis récemment retrouvé dans la même situation et suggère cette fonction pour MSTest:
public bool AssertThrows(Action action) where T : Exception
{
try {action();}
catch(Exception exception)
{
if (exception.GetType() == typeof(T)) return true;
}
return false;
}
usage:
Assert.IsTrue(AssertThrows<FormatException>(delegate{ newMyMethod(MyParameter); }));
Plus ici: http://phejndorf.wordpress.com/2011/02/21/assert-that-a-particular-exception-has-occured/
Comme je suis dérangé par la verbosité de certains des nouveaux modèles NUnit, j’utilise quelque chose comme ceci pour créer un code plus propre pour moi personnellement:
public void AssertBusinessRuleException(TestDelegate code, string expectedMessage)
{
var ex = Assert.Throws<BusinessRuleException>(code);
Assert.AreEqual(ex.Message, expectedMessage);
}
public void AssertException<T>(TestDelegate code, string expectedMessage) where T:Exception
{
var ex = Assert.Throws<T>(code);
Assert.AreEqual(ex.Message, expectedMessage);
}
L'utilisation est alors:
AssertBusinessRuleException(() => service.Create(content), "Name already exists");