'Preventing the use of junit4 libraries in a project
There is an existing software project, developed and maintained by several developers. The IDE is IntelliJ, the build tool is Maven. The project has had both JUnit 4 and JUnit 5 tests. We want to refactor and use only JUnit 5 from now.
The problem is that code completion from the IDE still offers both JUnit 4 and JUnit 5, and devs might accidentally use them, e.g. org.junit.Assert.assertTrue instead of org.junit.jupiter.api.Assertions.assertTrue.
Is there an elegant, automated way to detect the use of JUnit 4 classes as early as possible?
Solution 1:[1]
There are a few options once all the tests are converted from JUnit 4 to JUnit 5.
The most straightforward option is to exclude JUnit 4 from the classpath. Depending on what libraries are being used, some dependency-level exclusions might need to be added to avoid transitively pulling in JUnit 4. This setup will cause the build to fail at the compilation stage if any JUnit 4 imports are in use. It will also generally prevent the IDE from providing JUnit 4 classes as auto-completion options.
This option may not be available if another testing library requires JUnit 4. For instance, the Testcontainers library still requires JUnit 4 to be on the classpath, even if the tests themselves are written in JUnit 5 (testcontainers-java#970). In this case, one option is to write a Checkstyle rule to disallow non-Jupiter JUnit imports, and to have the build fail when Checkstyle failures occur.
The relevant Checkstyle config:
<module name="IllegalImport">
<property name="regexp" value="true"/>
<!-- Reject any org.junit import that's not also org.junit.jupiter: -->
<property name="illegalClasses" value="^org\.junit\.(?!jupiter\.).+"/>
</module>
Solution 2:[2]
If
junit4.x is not needed on classpath, you can remove it from classpath and add to the banned dependencies list ofmaven-enforcer-plugin:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>${maven-enforcer-plugin.version}</version> <executions> <execution> <id>enforce</id> <configuration> <rules> <bannedDependencies> <excludes> <exclude>junit:junit</exclude> </excludes> </bannedDependencies> </rules> </configuration> <goals> <goal>enforce</goal> </goals> </execution> </executions> </plugin>if
junit4.x is required to be on classpath (e.g.testcontainersstill depend on it), but you do not want other people to write tests using it -- use restrict-imports-enforcer-rule:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>${maven-enforcer-plugin.version}</version> <dependencies> <dependency> <groupId>de.skuzzle.enforcer</groupId> <artifactId>restrict-imports-enforcer-rule</artifactId> <version>2.0.0</version> </dependency> </dependencies> <executions> <execution> <id>enforce</id> <configuration> <rules> <RestrictImports> <reason>Please instead use Junit 5.</reason> <bannedImports> <bannedImport>org.junit.Test</bannedImport> <bannedImport>org.junit.runner.RunWith</bannedImport> <bannedImport>org.junit.Before</bannedImport> <bannedImport>org.junit.After</bannedImport> </bannedImports> </RestrictImports> </rules> </configuration> <goals> <goal>enforce</goal> </goals> </execution> </executions> </plugin>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Anastasiia Smirnova |
