Quick quiz, what is the output from the following JUnit test?

``` java package com.nearinfinity.sandbox; import junit.framework.TestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; public class ModelTest extends TestCase { @Before public void setUp() { System.out.println("Setup called."); } @After public void teardown() { System.out.println("Teardown called."); } @Test public void testSomething() { assertTrue(true); } } ```

If you said

``` java Setup has been called. Teardown has been called. ```

you'd be wrong. Don't feel bad though, I spent about two hours staring at a similar test until I finally figured out what was going on. So, what's the problem?

The problem lies in the mixed use of JUnit 3 and 4 concepts. The astute reader will notice that this test extends the JUnit 3 junit.framework.TestCase while also using JUnit 4 annotations. So which wins, the base class methods, the annotations, or both? Well, it turns out that the JUnit 3 base class conventions win out and the annotations are ignored. With that said, can you now guess what the test output is? Did you guess

``` console Setup has been called. ```

If not, don't feel bad. It's not immediately obvious. It turns out that the testSomething test method runs because it starts with the word test, not because it's decorated with the org.junit.Test annotation. The setUp method runs because it overrides junit.framework.TestCase's setUp method, not because it has a org.junit.Before annotation. Lastly, the teardown method doesn't run at all because it does not override the base class tearDown method due to the lowercase "d" and as we've seen, the org.junit.After annotation has no effect.

That lower case "d" cost me two hours of my life, which I now consider time well spent. It made me realize that my test's inheritance chain ultimately led to junit.framework.TestCase. The fact that the test had worked in the past was a textbook case of dumb luck.

So, if your JUnit 4 test classes start acting strange, make sure that base class you're extending doesn't ultimately lead to a junit.framework.TestCase.