Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@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?

like image 722
ChristophE Avatar asked Feb 19 '18 11:02

ChristophE


People also ask

What is the difference between junit5 and junit4?

Only one test runner can execute tests at a time in JUnit 4 (e.g. SpringJUnit4ClassRunner or Parameterized ). JUnit 5 allows multiple runners to work simultaneously. JUnit 4 never advanced beyond Java 7, missing out on a lot of features from Java 8. JUnit 5 makes good use of the Java 8 features.

Is JUnit 5 faster than junit4?

JUnit 5 is 10x slower than JUnit 4 #880.

Which of the following is life cycle annotation in junit5?

In JUnit 5, the test lifecycle is driven by four primary annotations i.e. @BeforeAll, @BeforeEach, @AfterEach and @AfterAll. Along with it, each test method must be marked with @Test annotation from package org. junit. jupiter.

What is @rule in junit5?

JUnit 4 annotations @Rule and @ClassRule do not exist in JUnit 5. Basically there is a new extension model that can be used to implement extensions with the same functionality. These extensions can be used with the @ExtendWith annotation.


1 Answers

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

like image 97
davidxxx Avatar answered Sep 19 '22 18:09

davidxxx