我遇到了一个问题,让Spock嘲笑一个接受单个byte[]
作为参数的方法。Spock:如何模拟接受单字节[]参数的方法?
被以相同的方式未能我的生产代码的简单的玩具实例如下:
import java.util.function.Consumer
import spock.lang.Specification
class ConsumerSpec extends Specification {
// ... elided ...
def '4: parameter is of an array type using single typed argument'() {
given:
def consumer = Mock(Consumer)
when:
consumer.accept([20, 21] as byte[])
then:
consumer.accept(_) >> { byte[] arg ->
assert arg[0] == 20
assert arg[1] == 21
}
}
// ... elided ...
}
的失败消息是
ConsumerSpec > 4: parameter is of an array type using single typed argument FAILED
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[[[email protected]]' with class 'java.util.Arrays$ArrayList' to class 'java.lang.Byte'
at groovy.lang.Closure.call(Closure.java:423)
at org.spockframework.mock.response.CodeResponseGenerator.invokeClosure(CodeResponseGenerator.java:53)
at org.spockframework.mock.response.CodeResponseGenerator.doRespond(CodeResponseGenerator.java:36)
at org.spockframework.mock.response.SingleResponseGenerator.respond(SingleResponseGenerator.java:31)
at org.spockframework.mock.response.ResponseGeneratorChain.respond(ResponseGeneratorChain.java:45)
at org.spockframework.mock.runtime.MockInteraction.accept(MockInteraction.java:76)
at org.spockframework.mock.runtime.MockInteractionDecorator.accept(MockInteractionDecorator.java:46)
at org.spockframework.mock.runtime.InteractionScope$1.accept(InteractionScope.java:41)
at org.spockframework.mock.runtime.MockController.handle(MockController.java:39)
at org.spockframework.mock.runtime.JavaMockInterceptor.intercept(JavaMockInterceptor.java:72)
at org.spockframework.mock.runtime.DynamicProxyMockInterceptorAdapter.invoke(DynamicProxyMockInterceptorAdapter.java:28)
at ConsumerSpec.4: parameter is of an array type using single typed argument(ConsumerSpec.groovy:52)
我依托于斯波克文档描述的行为Computing Return Values“基于交互的测试”。我选择转录如下相关位:
如果封闭声明了一个无类型参数,如果封闭宣布一个以上的参数或单一类型化的参数,它就会通过这个方法的参数列表... ,方法参数将逐个映射到关闭参数...
我在上面的规范中添加了一些其他测试,看看我是否理解了这些语句。完整的MCVE如下:
$ gradle这个--version
------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------
Build time: 2016-04-25 04:10:10 UTC
Build number: none
Revision: 3b427b1481e7303c90be7b05079b05b1c
Groovy: 2.4.4
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_91 (Oracle Corporation 25.91-b14)
OS: Linux 4.4.8-300.fc23.x86_64 amd64
//的build.gradle
plugins {
id 'groovy'
}
repositories {
mavenCentral()
}
dependencies {
testCompile(
[group: 'org.spockframework', name: 'spock-core', version: '1.0-groovy-2.4']
)
}
// SRC /测试/常规/ ConsumerSpec.groovy
import java.util.function.Consumer
import spock.lang.Specification
class ConsumerSpec extends Specification {
def '1: parameter is of a non-array type using single untyped argument'() {
given:
def consumer = Mock(Consumer)
when:
consumer.accept('value')
then:
consumer.accept(_) >> { args ->
String arg = args[0]
assert arg == 'value'
}
}
def '2: parameter is of a non-array type using single typed argument'() {
given:
def consumer = Mock(Consumer)
when:
consumer.accept('value')
then:
consumer.accept(_) >> { String arg ->
assert arg == 'value'
}
}
def '3: parameter is of an array type using single untyped argument'() {
given:
def consumer = Mock(Consumer)
when:
consumer.accept([20, 21] as byte[])
then:
consumer.accept(_) >> { args ->
byte[] arg = args[0]
assert arg[0] == 20
assert arg[1] == 21
}
}
def '4: parameter is of an array type using single typed argument'() {
given:
def consumer = Mock(Consumer)
when:
consumer.accept([20, 21] as byte[])
then:
consumer.accept(_) >> { byte[] arg ->
assert arg[0] == 20
assert arg[1] == 21
}
}
def '5: parameter is of an array type without using Mock'() {
given:
def consumer = { byte[] arg ->
assert arg[0] == 20
assert arg[1] == 21
} as Consumer<byte[]>
expect:
consumer.accept([20, 21] as byte[])
}
}
再一次,唯一失败的测试是(4)。
根据失败消息,就好像Spock或Groovy想要将嘲笑的方法视为Byte
s的可变参数方法,并将解包byte[]
参数。我唯一能够发现的问题听起来有点像我的问题,是GROOVY-4843,它是针对内置的Groovy模拟框架提出的,并且没有解决方案。
有没有办法让测试(4)的行为如预期?也就是说,能够在一个参数的闭包中使用类型化的数组参数?或者我坚持使用窗体(3)并且必须从无类型的闭包参数中提取实际的方法参数?
感谢您花时间做这项研究。它看起来与GROOVY-4843基本相同。我对Spock的历史并不熟悉,但是我不知道它是从原始的Groovy测试/嘲弄框架中分离出来的,并且继承了这个问题?对于@PeterNiederwieser会是一个好问题... –