How do I use Assert (or other Test class) to verify that an exception has been thrown?
How do I use Assert (or other Test class) to verify that an exception has been thrown?
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");
}
Usually your testing framework will have an answer for this. But if it's not flexible enough, you can always do this:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }
As @Jonas points out, this DOES NOT work for catching a base Exception:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // raises AssertionException
} catch (Exception) {
// Catches the assertion exception, and the test passes
}
If you absolutely must catch Exception, you need to rethrow the Assert.Fail(). But really, this is a sign you shouldn't be hand-writing this; check your test framework for options, or see if you can throw a more meaningful exception to test for.
catch (AssertionException) { throw; }
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();
}
if you use NUNIT, you can do something like this:
Assert.Throws<ExpectedException>(() => methodToTest());
It is also possible to store the thrown exception in order to validate it further:
ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);
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);
}
MSTest (v2) now has an Assert.ThrowsException function which can be used like this:
Assert.ThrowsException<System.FormatException>(() =>
{
Story actual = PersonalSite.Services.Content.ExtractHeader(String.Empty);
});
You can install it with nuget: Install-Package MSTest.TestFramework
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.github.io/docs/comparisons.html
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 github: http://xunit.github.io/
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()
You can achieve this with a simple one-line.
If your operation foo.bar() is async:
await Assert.ThrowsExceptionAsync<Exception>(() => foo.bar());
If foo.bar() is not async
Assert.ThrowsException<Exception>(() => foo.bar());
I know this thread is old and has many good answers but maybe worth mentioning that local function can help in a very simple way.
//Arrange
//Act
void LocalFunction() => mr.ActualMethod(params);
//Assert
Assert.Throws<Exception>(LocalFunction);
There is an awesome library called NFluent which speeds up and eases the way you write your assertions.
It is pretty straightforward to write an assertion for throwing an exception:
[Test]
public void given_when_then()
{
Check.ThatCode(() => MethodToTest())
.Throws<Exception>()
.WithMessage("Process has been failed");
}
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))]
Adding an example using FluentAssertions for those using that library.
// act
Action result = () => {
sut.DoSomething();
};
// assert
result.Should().Throw<Exception>();
// act
Func<Task> result = async () => {
await sut.DoSomethingAsync();
};
// assert
await result.Should().ThrowAsync<Exception>();
This works for Visual Studio Team Test (a.k.a MSTest)
While dealing with databases or http transaction. System should throw an exception somewhere, using Assert.ThrowExceptionAsync<>() will catch the your Throw event. (In these cases, Assert.ThrowException<>() does not catch the exception).
[TestMethod]
public void Invalid_Input_UserName_Should_Throw_Exception()
{
await Assert.ThrowExceptionAsync<ExpectedExceptionType>(()=> new LogonInfo(InvalidInputInUserNameFormat,"P@ssword"));
}