我正在编写 Spock 测试,并使用内联闭包来 stub 以实现简单的失败/通过行为。
def "test timeout"() {
given:
2 * feignClient.poll("foo") >>
{
int retries = 0;
if (retries < 1) {
retries++
throw newRetryable()
}
pollWaitSuccessResponseEntity
}
所以我尝试将闭包重构为命名的 Closure:
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
将只返回 x
1 * service.doSomething() >> { x }
将运行闭包中的代码并返回 x
因此,如果您想延迟响应代码的执行,但仍想将其放入变量中,则需要将执行包装在闭包中。
def myClosure = {
otherService.foo()
}
2 * service.doSomething() >> { myClosure() }
只要知道您可以使用响应链即可。
2 * feignClient.poll("foo") >> { throw newRetryable() } >> pollWaitSuccessResponseEntity
闭包代码的主要问题是,您将状态保留在闭包内,因此它将在每次调用时重置。您需要将重试计数器移出闭包,以便在调用之间保持状态。
关于groovy - 无法让 Spock stub 接受生成的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66888542/