Difference between JUnit4 and JUnit5
JUnit4 was divided into two modules that comprise JUnit5
1. JUnit Platform: This module covers all possible extension frameworks for test execution, discovery, and reporting.
2. JUnit Vintage: Backward compatibility with JUnit 4 and even JUnit 3 is possible with this module.
Annotations
Annotations in JUnit 5 have undergone significant modifications. The most significant change is that we can no longer declare expectations using the @Test annotation.
JUnit4
@Test(expected = Exception.class)
public void shouldRaiseAnException() throws Exception {
// ...
}

You can also try this code with Online Java Compiler
Run Code
@Test(timeout = 1)
public void shouldFailBecauseTimeout() throws InterruptedException {
Thread.sleep(10);
}

You can also try this code with Online Java Compiler
Run Code
JUnit5
public void shouldRaiseAnException() throws Exception {
Assertions.assertThrows(Exception.class, () -> {
//...
});
}

You can also try this code with Online Java Compiler
Run Code
@Test
public void shouldFailBecauseTimeout() throws InterruptedException {
Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10));
}

You can also try this code with Online Java Compiler
Run Code
Other Annotation which are changed in JUnit5 are as follows:
- @Before -> @BeforeEach
- @After -> @AfterEach
- @BeforeClass -> @BeforeAll
- @AfterClass -> @AfterAll
- @Ignore -> @Disable
Assertions
In JUnit 5, we may now create assertion messages in lambdas, allowing lazy evaluation to forgo complicated message generation unless it's absolutely necessary:
JUnit4
@Test
public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation() {
Assertions.assertTrue(
2 == 3,
() -> "Numbers " + 2 + " and " + 3 + " are not equal!");
}

You can also try this code with Online Java Compiler
Run Code
JUnit5
Test Program
@Test
public void incrementalArray() {
List<Integer> list = Arrays.asList(10, 20, 30);
Assertions.assertAll("Check if the array is incremental",
() -> Assertions.assertEquals(list.get(0).intValue(), 10),
() -> Assertions.assertEquals(list.get(1).intValue(), 20),
() -> Assertions.assertEquals(list.get(2).intValue(), 30));
}

You can also try this code with Online Java Compiler
Run Code
Assumptions
The new org.JUnit.jupiter.api contains Assumption class It not only support the assumption of JUnit4 but also add new features to JUnit5.
@Test
public void whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp() {
assumingThat("WEB".equals(System.getenv("ENV")),
() -> {
assertTrue("http".startsWith(address));
});
}

You can also try this code with Online Java Compiler
Run Code
Tagging & Filtering
We may use the @Category annotation in JUnit 4 to categorise tests. The @Category annotation has been superseded with the @Tag annotation in JUnit 5
@Tag("annotations")
@Tag("JUnit5")
@RunWith(JUnitPlatform.class)
public class AnnotationTestExampleTest {
/*...*/
}

You can also try this code with Online Java Compiler
Run Code
We can include/exclude particular tags using the maven-surefire-plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<properties>
<includeTags>JUnit5</includeTags>
</properties>
</configuration>
</plugin>
</plugins>
</build>
New Annotations for a Test run
In JUnit 4, the @RunWith annotation was used to connect the test environment with other frameworks or to modify the overall execution flow in test cases.
We can now utilise the @ExtendWith annotation with JUnit 5 to offer comparable functionality.
JUnit4
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
{"/app-config.xml", "/test-data-access-config.xml"})
public class SpringExtensionTest {
/*...*/
}

You can also try this code with Online Java Compiler
Run Code
JUnit5
@ExtendWith(SpringExtension.class)
@ContextConfiguration(
{ "/app-config.xml", "/test-data-access-config.xml" })
public class SpringExtensionTest {
/*...*/
}

You can also try this code with Online Java Compiler
Run Code
New Test rule Annotations
The @Rule and @ClassRule annotations in JUnit 4 were used to add additional functionality to tests. The @ExtendWith annotation in JUnit 5 may be used to replicate the same logic.
JUnit4
public class TraceUnitTestRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
// Before and after an evaluation tracing here
...
}
};
}
}

You can also try this code with Online Java Compiler
Run Code
And we implement the test suit as follows:
@Rule
public TraceUnitTestRule traceRuleTests = new TraceUnitTestRule();
JUnit5
public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback{
@Override
public void beforeEach(TestExtensionContext context) throws Exception{
// ...
}
@Override
public void afterEach(TestExtensionContext context) throws Exception{
// ...
}
}

You can also try this code with Online Java Compiler
Run Code
We can simply implement this rule in the test suite using JUnit 5's AfterEachCallback and BeforeEachCallback interfaces, which are available in the package org.JUnit.jupiter.api.extension:
@RunWith(JUnitPlatform.class)
@ExtendWith(TraceUnitExtension.class)
public class RuleExampleTest {
@Test
public void whenTracingTests() {
/*...*/
}
}

You can also try this code with Online Java Compiler
Run Code
JUnit5 Vintage
JUnit Vintage facilitates JUnit test migration by executing JUnit 3 or JUnit 4 tests in a JUnit 5 context. We may utilise it by adding the JUnit Vintage Engine to our project:
<dependency>
<groupId>org.JUnit.vintage</groupId>
<artifactId>JUnit-vintage-engine</artifactId>
<version>${JUnit5.vintage.version}</version>
<scope>test</scope>
</dependency>
FAQs
-
Is JUnit5 better than JUnit4?
Migrating tests from JUnit 4 to JUnit 5 may seem onerous if you've been using it for a long time. JUnit 5 takes advantage of technologies introduced in Java 8 or later, such as lambda functions, to make tests more powerful and maintainable.
-
Does Spring boot use JUnit4 or JUnit5?
Spring Boot's spring-boot-starter-test requirement imports the JUnit 4 dependencies by default. To utilise JUnit 5, we must remove JUnit 4 from the project dependencies and replace it with JUnit 5. We're utilising the most recent version of Spring Boot, which is 2.1.7.
-
Is TestNG better than JUnit?
TestNG has the ability to arrange test methods into Java groups. It runs unit tests using arguments passed into the test functions. The usage of Threads improves testing performance by reducing execution time. JUnit's issue of not being able to run concurrent tests has been overcome.
-
In JUnit5, which of the following annotations is used to rerun a test several times?
For a test function, instead of using the annotation @Test, the annotation @RepeatedTest is used. The input parameter of the annotation is set to a number. The execution is then performed as many times as the selected test method allows.
Key Takeaways
If you have reached till here that means you get significant idea how to migrate a JUnit 4 project to a new JUnit 5 version in this exercise. In JUnit 5, you learned how to maintain backward compatibility with JUnit 4.
Hope you wish to learn more about articles such as implementation of nested test in JUnit Hence never stop your quest to learning.
Happy Learning!