java.lang.RuntimeException:不支持:class org.spockframework.gentyref.CaptureTypeImpl
java.lang.RuntimeException: not supported: class org.spockframework.gentyref.CaptureTypeImpl
Spock 正用于在 Spring 引导项目 (2.1.18.RELEASE) 中执行集成测试。当我使用 1.3-groovy-2.5 运行 时,我得到这个错误:
Caused by: java.lang.RuntimeException: not supported: class org.spockframework.gentyref.CaptureTypeImpl
at org.spockframework.gentyref.GenericTypeReflector.erase(GenericTypeReflector.java:33)
at org.spockframework.mock.runtime.StaticMockMethod.getReturnType(StaticMockMethod.java:50)
at org.spockframework.mock.EmptyOrDummyResponse.respond(EmptyOrDummyResponse.java:68)
at org.spockframework.mock.runtime.MockController.handle(MockController.java:50)
at org.spockframework.mock.runtime.JavaMockInterceptor.intercept(JavaMockInterceptor.java:72)
at org.spockframework.mock.runtime.ByteBuddyInterceptorAdapter.interceptNonAbstract(ByteBuddyInterceptorAdapter.java:35)
at com.foo.controller.ConversionsController.createConversionJob(ConversionsController.java:68)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
... 18 more
如果我将 Spock 更新到更新的版本(例如 2.1-groovy-2.5),我会收到此错误:
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: org.spockframework.runtime.SpockEngine Unable to get public no-arg constructor
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:733)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:305)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:265)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1314)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1159)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:932)
[ERROR] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR] at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR] at org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
[ERROR] at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
[ERROR] at org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
我正在使用 Java 11 和 Maven 3.6.3。我的 pom.xml 相当长,所以我将其缩减为一些专注于版本和测试依赖性的片段:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<bytebuddy.version>1.11.0</bytebuddy.version>
<cglib.version>3.2.12</cglib.version>
<gmavenplus.version>1.12.0</gmavenplus.version>
<groovy.version>2.5.15</groovy.version>
<objenesis.version>3.2</objenesis.version>
<spock.version>1.3-groovy-2.5</spock.version>
<maven.buildhelper.version>3.3.0</maven.buildhelper.version>
<maven.jacoco.version>0.8.7</maven.jacoco.version>
<maven.surefire.version>3.0.0-M5</maven.surefire.version>
<maven.failsafe.version>3.0.0-M5</maven.failsafe.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<!-- uncommented for 2.1-groovy-2.5 -->
<!-- dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-junit4</artifactId>
<scope>test</scope>
</dependency -->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<scope>test</scope>
</dependency>
<dependency> <!-- enables mocking of classes (in addition to interfaces) -->
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>${bytebuddy.version}</version>
<scope>test</scope>
</dependency>
<dependency> <!-- enables mocking of classes without default constructor (together with ByteBuddy or CGLIB) -->
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis.version}</version>
<scope>test</scope>
</dependency>
<plugin>
<!-- The gmavenplus plugin is used to compile Groovy code. To learn more about this plugin,
visit https://github.com/groovy/GMavenPlus/wiki -->
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>${gmavenplus.version}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
<configuration>
<targetBytecode>11</targetBytecode>
</configuration>
</plugin>
非常感谢任何有助于进一步解决此问题的帮助。我根据 spock 框架项目中的示例对 pom.xml 进行了建模:
关于java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: org.spockframework.runtime.SpockEngine Unable to get public no-arg constructor
Spring Boot 2.1.18.RELEASE
真的很旧,它管理 JUnit 5 到 5.3.2
而 Spock 2.x 需要 >= 5.8
。如果无法升级 Spring 启动到更新的版本,您可以尝试设置 <junit-jupiter.version>5.8.1</junit-jupiter.version>
。
至于类型反射错误,由于您没有共享任何代码,我们不能说太多。只有那个 com.foo.controller.ConversionsController.createConversionJob(ConversionsController.java:68)
可能有一些奇怪的泛型或者正在调用一些东西。
我接受了 Leonard Brünings 的回答,因为它为我指明了正确的方向,但我想对问题的原因添加更多解释。
java.lang.RuntimeException: not supported: class org.spockframework.gentyref.CaptureTypeImpl
是一个反射错误,表明被模拟的方法有问题。
The exception points to the fact that it can't determine the correct response type of the stub method being called
我有这样的方法:
public class Foo {
public ResponseEntity<?> bar(Long id) {
...
}
}
在我的测试中我这样做了:
setup:
Foo mockFoo = Stub()
given:
String id = '123'
and:
ResponseEntity<String> response = new ResponseEntity<String>('Hello World', HttpStatus.OK)
and:
mockFoo.bar(id) >> response
...
因为 id
被声明为 String
而不是 Long
,抛出了异常。但是,当我将其更改为 Mock()
而不是 Stub()
并且还使用了基数规则时,很明显模拟方法没有被调用并显示更有用的错误消息:
then:
mockFoo.bar(id) >> response
0 * _ // don't allow any other interaction
Handler dispatch failed; nested exception is Too many invocations for:
0 * _ // don't allow any other interaction (1 invocation)
Spock 正用于在 Spring 引导项目 (2.1.18.RELEASE) 中执行集成测试。当我使用 1.3-groovy-2.5 运行 时,我得到这个错误:
Caused by: java.lang.RuntimeException: not supported: class org.spockframework.gentyref.CaptureTypeImpl
at org.spockframework.gentyref.GenericTypeReflector.erase(GenericTypeReflector.java:33)
at org.spockframework.mock.runtime.StaticMockMethod.getReturnType(StaticMockMethod.java:50)
at org.spockframework.mock.EmptyOrDummyResponse.respond(EmptyOrDummyResponse.java:68)
at org.spockframework.mock.runtime.MockController.handle(MockController.java:50)
at org.spockframework.mock.runtime.JavaMockInterceptor.intercept(JavaMockInterceptor.java:72)
at org.spockframework.mock.runtime.ByteBuddyInterceptorAdapter.interceptNonAbstract(ByteBuddyInterceptorAdapter.java:35)
at com.foo.controller.ConversionsController.createConversionJob(ConversionsController.java:68)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
... 18 more
如果我将 Spock 更新到更新的版本(例如 2.1-groovy-2.5),我会收到此错误:
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: org.spockframework.runtime.SpockEngine Unable to get public no-arg constructor
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:733)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:305)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:265)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1314)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1159)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:932)
[ERROR] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR] at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR] at org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
[ERROR] at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
[ERROR] at org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
我正在使用 Java 11 和 Maven 3.6.3。我的 pom.xml 相当长,所以我将其缩减为一些专注于版本和测试依赖性的片段:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<bytebuddy.version>1.11.0</bytebuddy.version>
<cglib.version>3.2.12</cglib.version>
<gmavenplus.version>1.12.0</gmavenplus.version>
<groovy.version>2.5.15</groovy.version>
<objenesis.version>3.2</objenesis.version>
<spock.version>1.3-groovy-2.5</spock.version>
<maven.buildhelper.version>3.3.0</maven.buildhelper.version>
<maven.jacoco.version>0.8.7</maven.jacoco.version>
<maven.surefire.version>3.0.0-M5</maven.surefire.version>
<maven.failsafe.version>3.0.0-M5</maven.failsafe.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<!-- uncommented for 2.1-groovy-2.5 -->
<!-- dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-junit4</artifactId>
<scope>test</scope>
</dependency -->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<scope>test</scope>
</dependency>
<dependency> <!-- enables mocking of classes (in addition to interfaces) -->
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>${bytebuddy.version}</version>
<scope>test</scope>
</dependency>
<dependency> <!-- enables mocking of classes without default constructor (together with ByteBuddy or CGLIB) -->
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>${objenesis.version}</version>
<scope>test</scope>
</dependency>
<plugin>
<!-- The gmavenplus plugin is used to compile Groovy code. To learn more about this plugin,
visit https://github.com/groovy/GMavenPlus/wiki -->
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>${gmavenplus.version}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
<configuration>
<targetBytecode>11</targetBytecode>
</configuration>
</plugin>
非常感谢任何有助于进一步解决此问题的帮助。我根据 spock 框架项目中的示例对 pom.xml 进行了建模:
关于java.util.ServiceConfigurationError: org.junit.platform.engine.TestEngine: org.spockframework.runtime.SpockEngine Unable to get public no-arg constructor
Spring Boot 2.1.18.RELEASE
真的很旧,它管理 JUnit 5 到 5.3.2
而 Spock 2.x 需要 >= 5.8
。如果无法升级 Spring 启动到更新的版本,您可以尝试设置 <junit-jupiter.version>5.8.1</junit-jupiter.version>
。
至于类型反射错误,由于您没有共享任何代码,我们不能说太多。只有那个 com.foo.controller.ConversionsController.createConversionJob(ConversionsController.java:68)
可能有一些奇怪的泛型或者正在调用一些东西。
我接受了 Leonard Brünings 的回答,因为它为我指明了正确的方向,但我想对问题的原因添加更多解释。
java.lang.RuntimeException: not supported: class org.spockframework.gentyref.CaptureTypeImpl
是一个反射错误,表明被模拟的方法有问题。
The exception points to the fact that it can't determine the correct response type of the stub method being called
我有这样的方法:
public class Foo {
public ResponseEntity<?> bar(Long id) {
...
}
}
在我的测试中我这样做了:
setup:
Foo mockFoo = Stub()
given:
String id = '123'
and:
ResponseEntity<String> response = new ResponseEntity<String>('Hello World', HttpStatus.OK)
and:
mockFoo.bar(id) >> response
...
因为 id
被声明为 String
而不是 Long
,抛出了异常。但是,当我将其更改为 Mock()
而不是 Stub()
并且还使用了基数规则时,很明显模拟方法没有被调用并显示更有用的错误消息:
then:
mockFoo.bar(id) >> response
0 * _ // don't allow any other interaction
Handler dispatch failed; nested exception is Too many invocations for:
0 * _ // don't allow any other interaction (1 invocation)