In 2019, I gave a talk at Netcentric Summit about Junit5 migration and its advantages. You can check the content here:

After 3 years, I wanted to revisit the procedure to migrate from junit4 to junit5, so let’s do it! The result was this PR.

Steps

1. Dependencies

1.2 Main pom.xml

In the main pom.xml, replace

<dependencyManagement>
    <dependencies>
...
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.xx</version>
            <scope>test</scope>
        </dependency>
...
   </dependencies>
</dependencyManagement>

by (check the latest version in https://mvnrepository.com/artifact/org.junit/junit-bom)

<dependencyManagement>
    <dependencies>
...
      <!-- Junit bill of materials -->
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>        
        <version>5.8.2</version>
        <type>pom</type>
        <scope>import</scope> 
      </dependency>
...
   </dependencies>
</dependencyManagement>

1.2 Module pom.xml

In the pom.xml of each module, replace

<dependencies>
...
   <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
...
</dependencies>

by

<dependencies>
...
    <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-api</artifactId>
       <scope>test</scope>
    </dependency>
    <!-- temporarily needed until the tests migration -->
    <dependency>
       <groupId>org.junit.vintage</groupId>
       <artifactId>junit-vintage-engine</artifactId>
       <scope>test</scope>
    </dependency>
...
</dependencies>

2. Code Migration

I use Intellij to migrate the code.

  1. Go to Refactor > Migrate packages and classes > Junit (4.x -> 5.x)
  2. Try to compile your code to see if all import were correctly replaced
  3. If it compiles ok, you have the basic migration done. In most of the cases we need to rewrite some tests.

3. Upgrading the tests

3.1 @Test(expected=…)

Junit 5 has a more elegant way of testing expected exceptions. If you have

@Test(expected=IllegalArgumentException.class)
public void testIfExceptionIsThrown() throws Exception {
    prepareMethod();
    methodCall();
}

you need to migrate to

@Test
void testIfExceptionIsThrown() {
    prepareMethod();
    assertThrows(IllegalArgumentException.class, () -> methodCall());
}

3.2 @RunWith(MockitoJUnitRunner.class)

If you have

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

you need to migrate to the ExtendWith and add a new dependency of Mockito.

Check the latest version at https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter.

New dependency:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.6.1</version>
    <scope>test</scope>
</dependency>

And then the new ExtendWith:

@ExtendWith(MockitoExtension.class)
public class MyClassTest {

3.3 Replace imports

Sometimes the migration fails to replace all imports. Do it manually

Old importNew import
import static org.mockito.Matchers.any;import static org.mockito.ArgumentMatchers.any;
import static org.junit.Assert.import static org.junit.jupiter.api.Assertions.

3.4 Unnecessary stubbings detected.

New Mockito versions are more strict about unnecessary stubbing and they want you to use strict stubbing. If you do not want to touch your tests yet to make them more strict, you will need to add another annotation to your class or add lenient to your mock.

Class configuration

Add @MockitoSettings(strictness = Strictness.LENIENT)

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class MyClassTest {
Test configuration

Add lenient() in front of each failed stubbing:

lenient().when(mock.getName()).thenReturn(name);

3.5 Parametrized tests

In Junit5 the parametrized tests were redesigned. Take a look on Parameterized Tests section.

References

  1. Migrating from JUnit 4 to JUnit 5 | The IntelliJ IDEA Blog
  2. Mockito and JUnit 5 - Using ExtendWith | Baeldung

If you found any error or want to help me to improve this article, please comment the pull request.