1. 概述
在本文中,我们将 学习如何修复 NoSuchMethodError 和 NoClassDefFoundError JUnit 错误 。当类 路径 中有两个不同的 JUnit 版本时,通常会出现此类问题。例如,当项目的 JUnit 版本与 Maven 或 Gradle 依赖项中使用的版本不同时,可能会出现这种情况。
2. Spring项目中JUnit的 NoClassDefFoundError
假设我们有一个使用 Spring Boot 2.1.2 和Spring Boot Starter Test依赖项的 Maven 项目。有了这样的依赖,我们可以使用 JUnit 5.3.2 编写和运行自动化测试,这是 spring-boot-test 依赖的 JUnit 版本。
现在,假设我们将继续使用 Spring Boot 2.1.2。但是,我们想要使用 JUnit 5.7.1。一种可能的方法是在 pom.xml 文件中包含 junit-jupiter-api 、 junit-jupiter-params 、 junit-jupiter-engine 和 junit-platform-launcher 依赖项:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
...
然而,在这种情况下,当我们运行测试时,我们会得到一个 NoClassDefFoundError :
[ERROR] java.lang.NoClassDefFoundError: org/junit/platform/commons/util/ClassNamePatternFilterUtils
如果我们迁移到 JUnit 5.4.0,将会出现 NoSuchMethodError ,而不是 NoClassDefFoundError 。
3. 理解并修复错误
如上一节所示,当我们尝试将 JUnit 版本从 5.3.2 迁移到 5.7.1 时,我们最终遇到了 NoClassDefFoundError 。
发生错误是因为 我们的 类路径 最终有两个不同版本的 JUnit 。因此,我们的项目是使用较新版本的 JUnit (5.7.1) 编译的,但在运行时发现了较旧版本 (5.3.2)。因此,JUnit 启动器尝试使用旧版本 JUnit 中不可用的类。
接下来,我们将学习修复此错误的不同解决方案。
3.1.覆盖 Spring 的 JUnit 版本
修复我们示例中的错误的有效方法是覆盖 Spring 管理的 JUnit 版本:
<properties>
<junit-jupiter.version>5.7.1</junit-jupiter.version>
</properties>
现在,我们还可以将 JUnit 依赖项替换为以下依赖项:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
这个单一依赖项将包括 junit-jupiter-api 、 junit-jupiter-params 和 junit-jupiter-engine 。通常仅当我们需要以编程方式运行 JUnit 测试时才需要 junit-platform-launcher 依赖项。
同样, 我们也可以在 Gradle 项目中覆盖托管版本 :
ext['junit-jupiter.version'] = '5.7.1'
3.2.适用于任何项目的解决方案
在上一节中,我们学习了如何修复 Spring 项目中的 NoSuchMethodError 和 NoClassDefFoundError JUnit 错误,这是最常见的场景。但是,如果发生这些错误并且我们的项目没有使用 Spring,我们可以尝试 修复 Maven 中的依赖冲突 。
与我们在 Spring 示例中发生的情况类似, 由于传递依赖关系,一个项目可能具有多个版本的 JUnit 。对于这样的场景,我们有一个关于如何解决 Maven 中的冲突的详细教程。
4。结论
在本教程中,我们重现并学习了如何修复 NoSuchMethodError 和 NoClassDefFoundError JUnit 错误。与往常一样,代码片段可以 在 GitHub 上找到。请注意,在此源代码示例中,我们覆盖了父项目的 pom.xml 文件中的 JUnit 版本。