Testing for exceptions with lambda expressions

Code coverage seems like that right thing to do, but is it worth the effort? While writing coverage tests, I found quite a few bugs (granted, they were small ones that probably never would have surfaced) which encouraged me to aim for 100% code coverage.

In my quest on the path of Test Enlightenment I find myself writing test after test to cover all of the different paths that can be traversed in a method. A lot of these are simply tests to check whether argument checking works as advertized.

Doing this with Visual Studio Unit Testing can be quite the chore, as the only way to write a test that checks for an exception is by adorning it with the ExpectedExceptionAttribute attribute. There’s a bunch of drawbacks with this:

  • You can’t scope where the exception should occur. The exception can be thrown anywhere in the test since the attribute is applied to the test method.
  • You can only check for one exception at a time. Normally you should be writing a test for one of these at a time, but this is pretty tedious and not really necessary.

Let’s have a look at such a test:

C#
1
2
3
4
5
6
[TestMethod] 
[ExpectedException(typeof(ArgumentNullException))] 
public void ContactHelpers_Require_Argument_1() 
{ 
    ContactHelpers.Print((Contact)null); 
}

Other unit testing frameworks augmented this ages ago when lambda’s were introduced into the language. In xUnit, for example, you can do the following:

C#
1
Assert.Throws<ArgumentNullException>(delegate { ContactHelpers.Print((Contact)null); });

...or since C# 3.0 using lambda expressions:

C#
1
Assert.Throws<ArgumentNullException>(() => ContactHelpers.Print((Contact)null) );

Like it? Well, there’s no reason why you can’t do this yourself. I wrote a small class that does the exception checking for me, so that I can use it in all my tests and be a lot more efficient. You can find it in the enclosed sample project.

It’s pretty easy to use, and looks similar to the xUnit example. Now, you simply do this:

C#
1
2
3
4
5
[TestMethod]
public void ContactHelpers_Require_Argument_1()
{
    Expect.Throw<ArgumentNullException>(() => ContactHelpers.Print((Contact)null));
}

I hope you enjoy it as much as I do.

Sample Code

The article contains sample code project(s).
You must be logged in to view or download sample code.
Sign in now

Comments

Leave a comment
You must be logged in to post comments.
Sign in now
 
 
Technical
Business
rss feed