无法让 Spock 存根以接受生成的闭包
Can't get Spock stubbing to accept a generated Closure
我正在编写 Spock 测试,并使用内联闭包来对简单的 fail/pass 行为进行存根。
def "test timeout"() {
given:
2 * feignClient.poll("foo") >>
{
int retries = 0;
if (retries < 1) {
retries++
throw newRetryable()
}
pollWaitSuccessResponseEntity
}
所以我尝试将闭包重构为命名闭包:
def retryClosure = {
int retries = 0;
if (retries < 1) {
retries++
throw newRetryable()
}
pollWaitSuccessResponseEntity
}
2 * feignClient.poll("foo") >> retryClosure
测试失败并出现以下错误:
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object
'com.example.service.FooServiceTest$__spock_initializeFields_closure2@3243178c' with class 'com.example..FooServiceTest$__spock_initializeFields_closure2' to class 'org.springframework.http.ResponseEntity'
Spock 严重依赖 AST 转换,因为必须使用某些结构。
1 * service.doSomething() >> x
只会 return x
1 * service.doSomething() >> { x }
将 运行 闭包中的代码和 return x
因此,如果您想延迟响应代码的执行,但仍想将它放在一个变量中,您需要将执行包装在一个闭包中。
def myClosure = {
otherService.foo()
}
2 * service.doSomething() >> { myClosure() }
只知道您可以改用响应链。
2 * feignClient.poll("foo") >> { throw newRetryable() } >> pollWaitSuccessResponseEntity
您的闭包代码的主要问题是您将状态保留在闭包内,因此每次调用都会重置它。您需要将重试计数器移出闭包,以便在调用之间保持状态。
我正在编写 Spock 测试,并使用内联闭包来对简单的 fail/pass 行为进行存根。
def "test timeout"() {
given:
2 * feignClient.poll("foo") >>
{
int retries = 0;
if (retries < 1) {
retries++
throw newRetryable()
}
pollWaitSuccessResponseEntity
}
所以我尝试将闭包重构为命名闭包:
def retryClosure = {
int retries = 0;
if (retries < 1) {
retries++
throw newRetryable()
}
pollWaitSuccessResponseEntity
}
2 * feignClient.poll("foo") >> retryClosure
测试失败并出现以下错误:
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object
'com.example.service.FooServiceTest$__spock_initializeFields_closure2@3243178c' with class 'com.example..FooServiceTest$__spock_initializeFields_closure2' to class 'org.springframework.http.ResponseEntity'
Spock 严重依赖 AST 转换,因为必须使用某些结构。
1 * service.doSomething() >> x
只会 return x
1 * service.doSomething() >> { x }
将 运行 闭包中的代码和 return x
因此,如果您想延迟响应代码的执行,但仍想将它放在一个变量中,您需要将执行包装在一个闭包中。
def myClosure = {
otherService.foo()
}
2 * service.doSomething() >> { myClosure() }
只知道您可以改用响应链。
2 * feignClient.poll("foo") >> { throw newRetryable() } >> pollWaitSuccessResponseEntity
您的闭包代码的主要问题是您将状态保留在闭包内,因此每次调用都会重置它。您需要将重试计数器移出闭包,以便在调用之间保持状态。