What order are the Junit @Before/@After called?
Yes, this behaviour is guaranteed:
The
@Before
methods of superclasses will be run before those of the current class, unless they are overridden in the current class. No other ordering is defined.
The
@After
methods declared in superclasses will be run after those of the current class, unless they are overridden in the current class.
One potential gotcha that has bitten me before:
I like to have at most one @Before
method in each test class, because order of running the @Before
methods defined within a class is not guaranteed. Typically, I will call such a method setUpTest()
.
But, although @Before
is documented as The @Before methods of superclasses will be run before those of the current class. No other ordering is defined.
, this only applies if each method marked with @Before
has a unique name in the class hierarchy.
For example, I had the following:
public class AbstractFooTest { @Before public void setUpTest() { ... }}public void FooTest extends AbstractFooTest { @Before public void setUpTest() { ... }}
I expected AbstractFooTest.setUpTest()
to run before FooTest.setUpTest()
, but only FooTest.setupTest()
was executed. AbstractFooTest.setUpTest()
was not called at all.
The code must be modified as follows to work:
public void FooTest extends AbstractFooTest { @Before public void setUpTest() { super.setUpTest(); ... }}
I think based on the documentation of the @Before
and @After
the right conclusion is to give the methods unique names. I use the following pattern in my tests:
public abstract class AbstractBaseTest { @Before public final void baseSetUp() { // or any other meaningful name System.out.println("AbstractBaseTest.setUp"); } @After public final void baseTearDown() { // or any other meaningful name System.out.println("AbstractBaseTest.tearDown"); }}
and
public class Test extends AbstractBaseTest { @Before public void setUp() { System.out.println("Test.setUp"); } @After public void tearDown() { System.out.println("Test.tearDown"); } @Test public void test1() throws Exception { System.out.println("test1"); } @Test public void test2() throws Exception { System.out.println("test2"); }}
give as a result
AbstractBaseTest.setUpTest.setUptest1Test.tearDownAbstractBaseTest.tearDownAbstractBaseTest.setUpTest.setUptest2Test.tearDownAbstractBaseTest.tearDown
Advantage of this approach: Users of the AbstractBaseTest
class cannot override the setUp
/tearDown
methods by accident. If they want to, they need to know the exact name and can do it.
(Minor) disadvantage of this approach: Users cannot see that there are things happening before or after their setUp
/tearDown
. They need to know that these things are provided by the abstract class. But I assume that's the reason why they use the abstract class