views:

3860

answers:

8

The title says it all - how do I use Assert (or other Test class?) do verify that an exception has been thrown?

Thanks :)

+10  A: 
try {
    somethingThatShouldThrowAnAcception();
    Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (Exception) { }

You should be able to adapt this approach to whatever you like -- including specifying what kinds of exceptions to catch. If you only expect certain types, finish the catch blocks off with:

} catch (GoodException) {
} catch (Exception) {
    // not the right kind of exception
    Assert.Fail();
}

EDIT: As you can see, there are some framework-specific solutions to your problem. This trick could come in handy later, when/if you're using another framework. ;) One advantage is that you get fine-grained control over which line is supposed to throw the exception.

ojrac
+1, I use this way instead of the attribute when I need to make assertions beyond just the type of exception. For example, what if one needs to check that certain fields in the exception instance are set to certain values.
Pavel Repin
+3  A: 

It is an attribute on the test method... you don't use Assert. Looks like this:

[ExpectedException(typeof(ExceptionType))]
public void YourMethod_should_throw_exception()
J.13.L
+20  A: 

For "Visual Studio Team Test" it appears you apply the ExpectedException attribute to the test's method.

Sample from the documentation here: A Unit Testing Walkthrough with Visual Studio Team Test

[TestMethod]
[ExpectedException(typeof(ArgumentException),
    "A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
   LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}
Kevin Pullin
Your answer was a bit more complete... :)
J.13.L
ExpectedException attribute above works in NUnit as well (but [TestMethod] should be [Test]).
dbkk
@dbkk: Doesnt work exactly the same in NUnit - the message is treated as a string that needs to matcvh the exception message (and IU think that makes more sense)
Ruben Bartelink
A: 

This is going to depend on what test framework are you using?

In MbUnit, for example, you can specify the expected exception with an attribute to ensure that you are getting the exception you really expect.

[ExpectedException(typeof(ArgumentException))]

Jay
A: 

Check out nUnit Docs for examples about:

[ExpectedException( typeof( ArgumentException ) )]
Jon Masters
+4  A: 

If you're using MSTest, which originally didn't have an ExpectedException attribute, you could do this:

try 
{
    SomeExceptionThrowingMethod()
    Assert.Fail("no exception thrown");
}
catch (Exception ex)
{
    Assert.IsTrue(ex is SpecificExceptionType);
}
Jon Limjap
+6  A: 

Be wary of using ExpectedException, as it can lead to several pitfalls as demonstrated here:

http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx

And here:

http://xunit.codeplex.com/Wiki/View.aspx?title=Comparisons#note1

If you need to test for exceptions, there are less frowned upon ways. You can use the try{act/fail}catch{assert} method, which can be useful for frameworks that don't have direct support for exception tests other than ExpectedException.

A better alternative is to use xUnit.NET, which is a very modern, forward looking, and extensible unit testing framework that has learned from all the others mistakes, and improved. One such improvement is Assert.Throws, which provides a much better syntax for asserting exceptions.

You can find xUnit.NET at CodePlex: http://www.codeplex.com/xunit

jrista
Alconja
A: 

In a project i´m working on we have another solution doing this.

First I don´t like the ExpectedExceptionAttribute becuase it does take in consideration which method call that caused the Exception.

I do this with a helpermethod instead.

Test

[TestMethod]
public void AccountRepository_ThrowsExceptionIfFileisCorrupt()
{
     var file = File.Create("Accounts.bin");
     file.WriteByte(1);
     file.Close();

     IAccountRepository repo = new FileAccountRepository();
     TestHelpers.AssertThrows<SerializationException>(()=>repo.GetAll());            
}

HelperMethod

public static TException AssertThrows<TException>(Action action) where TException : Exception
    {
        try
        {
            action();
        }
        catch (TException ex)
        {
            return ex;
        }
        Assert.Fail("Expected exception was not thrown");

        return null;
    }

Neat, isn´t it;)

Glenn