9

I'm looking for a way to catch exceptions globally in my NUnit project class library. So if one of my unit tests throws an exception, I can catch it in one spot. I don't want to surround each of my tests with a try/catch block. The reason I'm doing this is to print a nice error message with an explanation of the stack trace. In ASP.NET they have a method called Application_Error in Global.asax that does this sort of thing.

2 Answers 2

8
  1. You can create an Even listener: EventListeners (NUnit 2.4.4)

Interface

The extension object passed to Install must implement the EventListener interface:

public interface EventListener
{
    void RunStarted( string name, int testCount );
    void RunFinished( TestResult result );
    void RunFinished( Exception exception );
    void TestStarted(TestName testName);
    void TestFinished(TestResult result);
    void SuiteStarted(TestName testName);
    void SuiteFinished(TestResult result);
    void UnhandledException( Exception exception );
    void TestOutput(TestOutput testOutput);
}
  1. You can make the try/catch block less ugly using the delegates (lambda expression) and closures.

Here is how it works:

    public void Try(Action testCode)
    {
        try
        {
            testCode();
        }
        catch (Exception e)
        {
            Console.WriteLine("Nice Error Here: " + e.Message);
        }
    }

    [Test]
    public void TestO1()
    {
        int actual = 5;
        int expected = 4;
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void TestO2()
    {
        int actual = 5;
        int expected = 4;
        Try( () => Assert.AreEqual(expected, actual) );
    }

The method Try accepts the code as a parameter and executes it in the try block. So, in the catch block you can apply any necessary formatting.

The method TestO1 is just a usual unit test without any tricks.

The TestO2 has the assertion wrapped with the method Try:

Try( () => any line of code here );

It will be the same try/catch, but now I don’t need to write a lot of ugly code.

3

The EventListener is the way to go. However there is a knack: the UnhandledException will not be fired when an Assertion in your test fails. Rather use the TestFinished event to handle failed tests:

public void TestFinished(TestResult result)
{
    if (result.Executed && result.IsFailure)
    {
        Console.WriteLine(string.Format("Failure in test {0}", result.Name));
        Console.WriteLine(result.Message);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.