修复NoSuchMethodError JUnit错误

2023/05/12

1. 概述

在本文中,我们将学习如何解决NoSuchMethodError和NoClassDefFoundError JUnit错误。当我们的类路径中有两个不同的JUnit版本时,通常会出现此类问题。例如,当项目的JUnit版本与Maven或Gradle依赖项中使用的不同时,可能会发生这种情况。

2. Spring项目中的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 Launcher尝试使用旧版本的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-platform-launcher依赖项通常仅在我们需要以编程方式运行JUnit测试时才是必需的。

同样,我们也可以在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版本。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章