Exception Testing Pattern

Exception testing happens when we write test to assert that the code under test throws an exception when called with certain parameter. Since I started writing test, I have documented several steps which I can use to assert that my code under test throws a certain kind of exception. I even took to stackoverflow to see if I can get other people’s opinion on my approach and I’ll share my findings with you in this post.

To do this, I’ll be working with a tic tac toe game example that should throw exception when a null value is added to the game board. Below is my first approach:

//Arrange
int index = 1;
string value = null;

//Act
var ex = Assert.Throws(() => board.Add(key, value));

//Assert
Assert.IsType(ex);

This approach calls the code under test and gets the result returned from calling the code through the Assert.Throws and later performs the actual assert by checking that the returned type is of ArgumentException. This approach makes it hard to determine the purpose of the test because, we’re having two assert operation here, and we don’t know if we’re testing for a matching type or expecting an exception. It is therefore, not advisable to have multiple assert in a test. If you find yourself in this situation, you should take a second look at that test and pick out code which you can create another test for. One aspect I’ve found this approach useful is if I want to do a detailed assert on the exception thrown e.g

  • Check for a matching exception message: Assert.Equals("Error", ex.Message);
  • Assert that the inner exception is null: Assert.Null(ex.InnerException);

My second approach combines the Act and Assert parts:

int index = 1;
string value = null;

//Assert
Assert.Throws(() => board.Add(index, value));

This pattern combines the Act and Assert parts together (NUnit and xUnit supports this), making the test short and readable. This pattern is best if we do not need to perform detailed assert on the exception thrown.

On stackoverflow, jimmy keen suggested another approach which is closely related to the second approach above.

//Arrange
int index = 1;
string value = null;

//Act
Action addNullValue = () => board.Add(key, value);

//Assert
Assert.Throws(addNullValue);

This pattern tries to make the test readable as compared to my first approach by wrapping the code under test in an Action delegate. This pattern is basically the same as the second, except that it wraps the code under test in a delegate which is passed to the Assert.Throws method. But basically, the code under test is executed when Assert.Throws is called.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s