Skip to content
Advertisement

@Before/@BeforeEach inheritance behaviour change JUnit4 / JUnit5

When migrating from JUnit4 to JUnit5 I found a change in the behaviour of JUnit4 and JUnit5 and wanted to check if the change was a bug in JUnit4 or in JUnit5 and how to do it correctly.

Lets assume the following structure:

One base class

public class BaseTestClass {

    @Before
    public void setUp(){
        System.out.println("Base Test Class");
    }
}

Another class that inherits from this base class

public class InheritsFromBase extends BaseTestClass {

    @Override
    public void setUp() {
        System.out.println("I inherit from base");

        super.setUp();
    }
}

And an actual test class

public class ActualTests extends InheritsFromBase {

    @Test
    public void myTest(){
        Assert.assertTrue(true);
    }
}

If I run myTest() in JUnit 4 then the setUp() method of both, BaseTestClass and InheritsFromBase is called.

After migrating this code to JUnit5, the setUp() methods are not called anymore. I had to manually add the @BeforeEach annotation on InheritsFromBase.

Resulting in the following classes:

public class BaseTestClass {

    @BeforeEach
    public void setUp(){
        System.out.println("Base Test Class");
    }
}

public class InheritsFromBase extends BaseTestClass {

    @Override
    @BeforeEach
    public void setUp() {
        System.out.println("I inherit from base");

        super.setUp();
    }
}

public class ActualTests extends InheritsFromBase {

    @Test
    public void myTest(){
        Assertions.assertTrue(true);
    }
}

So my question: Was the behaviour in JUnit4 correct or in JUnit5?

Advertisement

Answer

The actual behavior for JUnit 5 is expected as the @BeforeEach javadoc states :

Inheritance

@BeforeEach methods are inherited from superclasses as long as they are not overridden.

You override the setup() method that contains @BeforeEach in the InheritsFromBase class.
So it is not inherited any longer.

For JUnit 4, the @Before javadoc doesn’t state any particularity and inheritance abilities.
So you should consider the actual behavior as “normal” but no documented.

To get the same behavior with JUnit 5, you should do the reverse what you do with JUni4 : remove @BeforeEach in the super class and add it only in the subclass.

public class BaseTestClass {

    public void setUp() {
        System.out.println("Base Test Class");
    }
}


public class InheritsFromBase extends BaseTestClass {

    @Override
    @BeforeEach
    public void setUp() {
        System.out.println("I inherit from base");
        super.setUp();
    }
}

As I execute the tests, it produces as output :

I inherit from base

Base Test Class

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement