All things personal

Malte Finsterwalder's Blog

Posts tagged coding

Apr 16

JUnit “Catch unexpected Exception”-Anti-Pattern

When I look at codebases, I often see the following anti-pattern in JUnit tests:

@Test
public void testmethod() {
    // do something
    try {
        // do something that throws a checked exception
    } catch (Exception e) {
        fail(e.getMessage());
    }
    // do some more
}

The problem with this construct is, that it swallows the stacktrace. You only get a failure with the message of the exception. And besides it’s a lot of work to write all the try-catch blocks and they clutter the code.

Exceptions that should not occur in a test should just be thrown out of the test method. JUnit will catch them, show the test as failing and give you the stacktrace in all it’s glory.

So it’s better and easier to just write the code as follows:

@Test
public void testmethod() throws Exception {
    // do something
    // do something that throws a checked exception
    // do some more
}

Catching exceptions in tests only makes sense, when you want to test, that an exception occurs.

@Test
public void testThatExceptionIsThrown() {
    // do something
    try {
        // do something that should throw an exception
        fail("XyzException expected");
    } catch (XyzException expected) {
        assertEquals("BlaBlaBla...", expected.getMessage());
    }
    // do some more
}

If you are only interested that the exception occurs at all and don’t want to verify anything on it, JUnit 4 makes it even easier:

@Test(expected=XyzException.class)
public void testThatExceptionIsThrown() {
    // do something
    // do something that should throw an exception
}

This test fails, if the expected exception is not thrown (either because no exception or another exception was thrown). But beware, that you can’t know for sure in which call the exception occured. If multiple methods in the test could raise the exception in question, a try-catch-block is more specific.