Art Of Programming

musings by Dmytrii Nagirniak

Testing Expected Exception, Revisited

I have been using NUnit for a long time and really got used to it. Nowadays it is very sweet, especially with NUnitEx.
It does have a simple syntax for testing exception. Pretty much what I did long time ago.
It looks like this:
[Test]
public void ThrowsAndGivesMessage() {
    Assert.Throws<FormModelProviderException>(() => new XmlFormModelProvider().CreateModel());
}
BUT, it does not allow me to verify the actual message of the exception. I want to write the code like this to do that:
[Test]
public void ThrowsAndGivesMessage() {
    Action act = () => new XmlFormModelProvider().CreateModel();
    act.Throws<FormModelProviderException>()
        .Message
        .Should().Contain("Form/Form element is not found");
}

The point here is that I verify the exception type thrown AND get the TYPED exception as the result of the verification so I can do whatever I want with it. One more thing I like is that we explicitly see the acting code.
Ohh, yes. The code to support this:
public static TExpected Throws<TExpected>(this Action a) where TExpected : Exception {
    try {
        a.Invoke();
    } catch (TExpected expected) {
        return expected;     
    } catch (Exception other) {
        Assert.Fail(string.Format("Expected exception of type {0} but {1} was raised.", typeof(TExpected).Name, other.GetType().Name));
    }
    Assert.Fail(string.Format("The expected exception {0} has not been raised", typeof(TExpected).Name));
    return null; // This NULL smells - should be refactored :)
}

Enjoy.

Comments