Use Caution when Mixing JUnit 3 and 4

| | Comments (0) | TrackBacks (0)

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

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

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

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.

Leave a comment

0 TrackBacks

Listed below are links to blogs that reference this entry: Use Caution when Mixing JUnit 3 and 4.

TrackBack URL for this entry: http://www.nearinfinity.com/mt/mt-tb.cgi/538