Migrate JUnit 4 to JUnit 5 using IntelliJ IDEA

IntelliJ IDEA provides a basic built-in support to migrate JUnit 4 to JUnit 5 tests. Even most of the steps to migrate JUnit 4 to JUnit 5 are already explained in the Jetbrains blog “Migrating from JUnit 4 to JUnit 5”, I would like to focus here on aspects that the current IDEA IntelliJ version, 2021.3.3 (Ultimate Edition) Build #IU-213.7172.25, build on March 15, 2022, does not cover.

To enable the migration support you must enable the inspection in in Preferences | Editor | Inspections | JVM languages | JUnit 4 test can be JUnit 5.

After you activated the inspection the migration is available at the class level and you can access a migration action through the menu Refactor | Migrate Packages and Classes | Junit.

NOTE: The action is not available through the context menu Refactor and you will not find it through an action search. For details take a look at IDEA-291948.

The current migration action works well, but it does not support:

Exception tests

If you have a JUnit 4 test that expects an exception it might look like this:

@Test(expected = IndexOutOfBoundsException.class)
 public void getElementOutOfBounds() {
     List<Object> list = new ArrayList<>();
     list.add(new Object()); 
     list.get(1);
 }

IntelliJ IDEA does not migrate those test. You must manually migrate them to

@Test
public void getElementOutOfBounds() {
    Assertions.assertThrows(IndexOutOfBoundsException.class, () -> {
        List<Object> list = new ArrayList<>();
        list.add(new Object());
        list.get(1);
    });
}

Sadly there is no simple regex pattern to safely migrate these kind of test methods. If I find one some day I will update this blog. Maybe you found one and would like to add a comment.

NOTE: There is an open issue at the JB Jira IDEA-230146. Hopefully it will be implemented soon.

Accessibility

JUnit 5 allows to reduce the accessibility of test classes and methods to package (default) scope. E.g.

@Test
void getAtIndex() {
    Assert.assertEquals("A", Arrays.asList("A").get(0));
}

It seems to be unimportant to change the modifier, but changing the modifier reduces the accessibility and thus these classes will not appear in type import suggestions and other type searches, This reduces the risk to accidentially select wrong types and reduces the suggestion candidates in the IDE.

IntelliJ IDEA does also not provide a migration for the accessibility. But you can achieve it easily using regular expressions.

Use Replace in Files with the search pattern @Test(\n\s*)public void and the replace pattern @Test$1void

It will be a goad idea to commit your files between each step or make another kind of backup.

NOTE: IntelliJ IDEA will not show the replacement correctly, because the preview does not honor whitespaces.

But try it on one occurence and you will see that it works.

The class accessibility can be changed with the search pattern public class (.*)Test and the replace pattern class $1Test.

Leave a Reply

Your email address will not be published. Required fields are marked *