Wednesday, August 19, 2009

Exception Expected? Assert.True ...

Awhile back, Ayende Rahien posted about Assert.True as a tool of last resort. It was a great post (if you're into testing, which if you're a developer, I'm assuming you are, you should read it) and I chimed in about a pattern that bothered me:

...
bool handled = false;

try 
{
   something;
}
catch(Exception ex)
{
   handled = true;
}

Assert.IsTrue(handled);
...

Tests are meant to ensure appropriate behavior. Our methods validate their contracts early by testing the parameters passed in. If I am expecting something not to be null, and you give me a null, it's my obligation as your friend to pass back an ArgumentNullException instead of letting it flow through until you get a NullReference.

Someone replied about a helper method and I had that "slap forehead" moment because I hadn't thought of this:

private delegate void ExceptionDelegate();

private static bool _ExceptionExpected(Type exceptionType, ExceptionDelegate method)
{
    bool retVal = false;

    try
    {
        method(); 
    }
    catch(Exception ex)
    {
        retVal = ex.GetType() == exceptionType;                
    }

    return retVal; 
}

...
Assert.IsTrue(_ExceptionExpected(typeof(ArgumentNullException), () => targetClass.TargetMethod(null)));

A lot cleaner and reusable ... and I'm confident someone reading this will come back with something even more elegant, but for now, I like it!

Jeremy Likness