运行Spock Spring Boot单元测试时遇NoSuchMethodError错误求助
问题解决:Spock + Spring Boot 测试中Surefire插件报错NoSuchMethodError
背景
使用Spock测试框架编写Spring Boot应用的单元测试,已声明以下测试依赖:
spock-spring: 2.3-groovy-4.0spring-boot-starter-test: 3.2.4surefire plugin version: 3.2.2
问题现象
执行mvn test时,Surefire插件执行测试失败,报错如下:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.2.2:test (default-test) on project myspockspringtest: [ERROR] [ERROR] Please refer to C:\data\ myspockspringtest\target\surefire-reports for the individual test results. [ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream. There was an error in the forked process 'java.util.Set org.junit.platform.engine.TestDescriptor.getAncestors()'
查看dump文件,发现具体错误:
java.lang.NoSuchMethodError: 'java.util.Set org.junit.platform.engine.TestDescriptor.getAncestors()' at org.junit.platform.launcher.core.StackTracePruningEngineExecutionListener.getTestClassNames(StackTracePruningEngineExecutionListener.java:50)
已尝试操作
- 声明Spock的物料清单
spock-bom确保依赖一致性,问题未解决:
<dependencyManagement> <dependencies> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-bom</artifactId> <version>2.3-groovy-4.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
- 未声明
spock-bom时测试,仍出现相同错误。
问题原因
这个错误是JUnit Platform版本不兼容导致的:
- Spock 2.3-groovy-4.0依赖的是JUnit Platform 1.9.x,该版本中
TestDescriptor.getAncestors()方法返回类型为java.util.Set。 - Spring Boot 3.2.4自带的JUnit Platform版本是1.10.x,在这个版本里,
getAncestors()方法的返回类型被改为了java.util.List,方法签名发生了变化。 - 当Surefire插件运行测试时,加载了Spring Boot引入的JUnit Platform 1.10.x类,而Spock的代码仍然调用旧的方法签名,因此抛出
NoSuchMethodError。
解决方案
有两种可靠的解决方式:
1. 升级Spock版本到兼容JUnit Platform 1.10的版本
Spock 2.4-groovy-4.0及以上版本已经支持JUnit Platform 1.10.x,直接更新依赖即可:
<!-- 更新spock-spring版本 --> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-spring</artifactId> <version>2.4-groovy-4.0</version> <scope>test</scope> </dependency> <!-- 同时更新spock-bom(如果使用的话) --> <dependencyManagement> <dependencies> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-bom</artifactId> <version>2.4-groovy-4.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2. 降级Spring Boot版本到3.1.x
Spring Boot 3.1.x系列使用的是JUnit Platform 1.9.x,和Spock 2.3-groovy-4.0兼容,修改Spring Boot的父依赖版本即可:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.10</version> <!-- 3.1.x的最新稳定版 --> <relativePath/> </parent>
不推荐的临时方案(不建议使用)
如果暂时无法升级或降级,可以在dependencyManagement中强制指定JUnit Platform的版本为1.9.x,但可能会引发其他Spring Boot测试组件的兼容问题:
<dependencyManagement> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-engine</artifactId> <version>1.9.3</version> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <version>1.9.3</version> </dependency> </dependencies> </dependencyManagement>
内容的提问来源于stack exchange,提问作者roj
相关产品推荐
相关产品推荐

