Saturday, August 24, 2013

How to create a unit test that expect an exception?

In creating unit tests, we want to get maximum code coverage to make sure we are testing all possible scenarios and outcomes of our code. When we have a possible path of execution that leads into an exception being thrown, how do we build a test for that?

Consider this simple method "GoToPage" that takes in an integer as a parameter in the "Book" class.
public class Book
{
    // ...

    public void GoToPage(int page) 
    {
        if (page < 1)
            throw new ArgumentException("Page must be a positive, non-zero integer", "page"); 
        if (page > TotalPage)
            throw new ArgumentException("Page cannot be more than the total page count", "page"); 

        // ...
    }

    // ...
}
So how do we test those boundary scenarios? We can do something like this:
[TestMethod]
public void NegativePage_Exception()
{
    // arrange
    var book = new Book();

    // act
    try 
    {
        // act
        book.GoToPage(-1);
    }
    catch (ArgumentException e)
    {
        // assert
        Assert.AreEqual("Page must be a positive, non-zero integer", e.Message);
    }
    catch (Exception) {
        Assert.Fail();
    }
}
Or, you can write a more concise test such as this:
[TestMethod]
[ExpectedException(typeof(ArgumentException), "Page must be a positive, non-zero integer")]
public void NegativePage_Exception()
{
    // arrange
    var book = new Book();

    // act
    book.GoToPage(-1);
}

No comments: