Skip to content

Migration from JUnit 4 to JUnit 5

Kai Martins-Turner edited this page Jan 4, 2024 · 4 revisions

Guide to switch MATSim projects from JUnit 4 to JUnit 5

General Remarks

Most of the steps can be done automatically, only the change from Rule to RegisterExtension and the change of parameterized tests must be done by hand.

Original PR including some discussion on the switch can be found here: https://github.com/matsim-org/matsim-libs/pull/2988

Steps to be done

  1. Switch to JUnit 5 imports by adding
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.10.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.10.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>

to your pom.xml. Note that we import the vintage package here, such that the old junit 4 code still compiles.

  1. Manual step: change some annotations be IntelliJ text replacement.
  • @Rule annotation of MatsimTestUtils to @RegisterExtension
  • @Before to @BeforeEach --> see https://www.baeldung.com/junit-5-migration#1-annotations Please note: There might be other annotations that were not changed by the scripts in the following steps Don't forget to replace the old import(s) by the new one(s) accordingly, e.g. to import org.junit.jupiter.api.extension.RegisterExtension; and import org.junit.jupiter.api.BeforeEach;.
  1. Switch the Assertions from JUnit 4 to JUnit 5 by using this recipe:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-testing-frameworks:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.testing.junit5.AssertToAssertions

Source: https://docs.openrewrite.org/recipes/java/testing/junit5/asserttoassertions

  1. Switch the @Test annotations from JUnit 4 to Junit 5 by using this recipe:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-testing-frameworks:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.testing.junit5.UpdateTestAnnotation

Source: https://docs.openrewrite.org/recipes/java/testing/junit5/updatetestannotation

  1. Switch from @RunWith(Parameterized.class) to ParameterizedTest manually. Repeat the follwing steps for each class which is parameterized:

    • Delete the RunWith class annotation
    • Delete all the class fields which are parameterized (also the constructor)
    • Change the @Parameters method to a method returning either Stream<Arguments> (if there are multiple arguments) or Stream<SomeObject> (if there is one arugment of class SomeObject).
    • Add the parameters to each test which is parameterized (use the same names as for the class fields - that makes refactoring easier)
    • For each parameterized test change the @Test annotation to @ParameterizedTest and @MethodSource(<yourParametersMethod>). Note that you could also use @ValueSource or @EnumSource if you only have a few parameters.
    • Resolve other issues such that maven build works.
  2. Clean up old JUnit 4 imports by using this recipe:

mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-testing-frameworks:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.testing.junit5.CleanupJUnitImports

Source: https://docs.openrewrite.org/recipes/java/testing/junit5/cleanupjunitimports.

This recipe doesn't find all junit 4 imports. The imports for parameterized test can be found by hand via import\s+org\.junit\b(?!\.jupiter\b) in IntelliJ (switch on RegEx). Delete them by hand.

  1. Delete the import of the vintage package. If you have MATSim as a parent project in our pom, please also remove the version from the other two dependencies. This gets inherited from the parent project. In this case the following should now be part of your pom:
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>
  1. Check if everything compiles and fix errors by hand.

  2. You're finished :-)

Clone this wiki locally