Problem
How can I verify that an exception has been thrown using Assert (or another Test class)?
Asked by Alex
Solution #1
It appears that the ExpectedException attribute is applied to the test function for “Visual Studio Team Test.”
Here’s an example from the documentation: A Visual Studio Team Test Unit Testing Walkthrough
[TestMethod]
[ExpectedException(typeof(ArgumentException),
"A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}
Answered by Kevin Pullin
Solution #2
In most cases, your testing framework will provide a solution. However, if it isn’t flexible enough, you may always perform the following:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }
This DOES NOT work for catching a basic Exception, as @Jonas points out:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // raises AssertionException
} catch (Exception) {
// Catches the assertion exception, and the test passes
}
You must rethrow the Assert if you really must catch Exception. Fail(). However, this is a clue that you shouldn’t be writing this by hand; look into your test framework for alternatives, or see if you can throw a more significant exception to test for.
catch (AssertionException) { throw; }
You should be able to customize this technique to your preferences, including defining which exceptions to catch. If you’re just expecting a few types, end the catch blocks with:
} catch (GoodException) {
} catch (Exception) {
// not the right kind of exception
Assert.Fail();
}
Answered by ojrac
Solution #3
My preferred method for accomplishing this is to create a Throws method and utilize it in the same way as any other Assert method. Because.NET does not allow you to construct a static extension method, you won’t be able to use this method as if it were part of the built-in Assert class; instead, create a new class called MyAssert or something like. This is how the class looks:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace YourProject.Tests
{
public static class MyAssert
{
public static void Throws<T>( Action func ) where T : Exception
{
var exceptionThrown = false;
try
{
func.Invoke();
}
catch ( T )
{
exceptionThrown = true;
}
if ( !exceptionThrown )
{
throw new AssertFailedException(
String.Format("An exception of type {0} was expected, but not thrown", typeof(T))
);
}
}
}
}
As a result, your unit test should look like this:
[TestMethod()]
public void ExceptionTest()
{
String testStr = null;
MyAssert.Throws<NullReferenceException>(() => testStr.ToUpper());
}
Which is much more similar to the rest of your unit test syntaxes in appearance and behavior.
Answered by Richiban
Solution #4
You can accomplish something like this with NUNIT:
Assert.Throws<ExpectedException>(() => methodToTest());
It’s also feasible to save the thrown exception and use it later to validate it:
ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);
See: http://nunit.org/docs/2.5/exceptionAsserts.html
Answered by damir
Solution #5
If you’re using MSTest, which didn’t come with an ExpectedException attribute at first, you may do something like this:
try
{
SomeExceptionThrowingMethod()
Assert.Fail("no exception thrown");
}
catch (Exception ex)
{
Assert.IsTrue(ex is SpecificExceptionType);
}
Answered by Jon Limjap
Post is based on https://stackoverflow.com/questions/933613/how-do-i-use-assert-to-verify-that-an-exception-has-been-thrown