如何统计闭包方法调用次数?基于Spock框架的测试需求
验证Spock中闭包的调用次数
在Spock里,直接用1 * greeting这种语法是行不通的——因为这个交互测试语法是专门给Mock/Spy对象设计的,普通闭包不属于这类可监控对象。不过有两种优雅的方式可以实现你的需求:
方法一:用Spy包装闭包(推荐,更符合Spock风格)
你可以把原闭包用Spock的Spy包装起来,这样就能捕获它的调用次数了。Spy会保留原闭包的功能,同时允许你监控它的调用行为:
class SomeTestSpec extends Specification { @Unroll def "test closure call count"() { given: // 用Spy包装闭包,保留原逻辑 def greeting = Spy(Closure) { call() >> "Hello world!" } when: def v = greeting() // 这里调用的是Spy包装后的闭包 then: // 验证闭包的call方法被调用了1次(闭包调用本质是调用call()) 1 * greeting.call() // 同时可以验证返回值是否正确 v == "Hello world!" } }
方法二:手动统计调用次数(简单直接,适合快速场景)
如果不想用Mock/Spy,也可以在闭包里嵌入一个计数器变量,手动跟踪调用次数:
class SomeTestSpec extends Specification { @Unroll def "test closure call count"() { given: def callCount = 0 def greeting = { callCount++ // 每次调用时自增计数器 "Hello world!" } when: def v = greeting() then: callCount == 1 // 验证计数器的值 v == "Hello world!" } }
为什么不能直接用1 * greeting?
Spock的n * target.method()语法是基于动态代理的,只能作用于实现了接口的对象或者Groovy的动态对象。普通闭包虽然是Groovy对象,但直接用1 * greeting会被解析为“验证greeting这个属性被访问了1次”,而不是闭包被调用了1次——这和你的需求完全不符,所以必须用上面两种方法来实现。
内容的提问来源于stack exchange,提问作者user1266570
相关产品推荐
相关产品推荐

