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?
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.
JUnit 5 is 10x slower than JUnit 4 #880.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With