Here's the scenario: a unit test throws an uncaught exception, but then so does tearDown()
. What happens? TestCase.runBare()
says:
public void runBare() throws Throwable { setUp(); try { runTest(); } finally { tearDown(); } }
See the problem? If tearDown()
throws, then runBare()
loses any exception thrown by runTest()
(which runs your unit test). [See the Java Language Specification, §11.3.] Rarely is this what you actually want since the lost exception was the original cause of test error. The solution—override runBare()
:
public void runBare() throws Throwable { Throwable thrown = null; setUp(); try { runTest(); } catch (final Throwable t) { thrown = t; } finally { try { tearDown(); if (null != thrown) throw thrown; } catch (Throwable t) { if (null != thrown) throw thrown; else throw t; } } }
The idea is simple. Store the exception from runTest()
and rethrow it after running tearDown()
. Make sure to throw any exception from tearDown()
otherwise.
UPDATE: My brain finally caught up with my fingers and I realize that the sample solution is unnecessarily complex. Better is:
public void runBare() throws Throwable { Throwable thrown = null; setUp(); try { runTest(); } catch (final Throwable t) { thrown = t; } finally { try { tearDown(); } finally { if (null != thrown) throw thrown; } } }