如何测试Groovy类中字段是否被设置为指定值(Spock测试场景)
解决Spock Spy中验证字段赋值的问题
嘿,我明白你遇到的问题了——用Spock Spy测试Groovy类里的something字段赋值,之前试了交互验证但可能没达到预期对吧?这其实是因为Groovy的字段和自动生成的setter之间的小特性在搞鬼,我给你拆解两种靠谱的解决方式:
一、先搞懂核心问题:字段直接赋值 vs 调用setter
Groovy里如果你的类是这么写的:
class MyClass { def something void clearSomething() { something = null // 直接给字段赋值,不会触发自动生成的setSomething方法 } void setSomethingExplicitly() { setSomething(new Bubble()) // 显式调用setter } }
注意这两种赋值的区别:直接给字段赋值时,Groovy不会调用自动生成的setter方法,这时候你用1 * spyCUT.setSomething(null)这种交互验证肯定会失败,因为这个方法根本没被调用!
二、方案1:直接验证字段的最终状态(最稳妥的内部赋值场景)
因为Spock的Spy是真实的对象实例,你可以直接检查它的字段状态,有两种方式:
- 用Groovy自动生成的getter(推荐,符合封装原则)
- 直接访问底层字段(Groovy语法支持,用
@前缀)
比如测试clearSomething方法的then块可以这么写:
then: // 用getter,Groovy会自动调用getSomething() spyCUT.something == null // 或者直接访问字段(适合需要绕过getter逻辑的场景) spyCUT.@something == null
如果是验证字段被设置为Bubble实例,还可以检查类型或实例属性:
then: spyCUT.something instanceof Bubble // 如果Bubble有自定义属性,还能验证具体值 spyCUT.something.name == "test-bubble"
三、方案2:验证setter方法的调用(适合显式调用setter的场景)
如果你的代码是显式调用setter方法(比如上面的setSomethingExplicitly),那你最初的思路是对的,交互验证可以正常工作:
then: 1 * spyCUT.setSomething(_ as Bubble) // 验证调用过setter,参数是Bubble类型 // 或者精确匹配参数(需要Bubble有正确的equals方法) 1 * spyCUT.setSomething(new Bubble(name: "test"))
完整测试示例
给你一个完整的测试用例参考:
class MyClassSpec extends Specification { def "test clearSomething sets something to null"() { given: def spyCUT = Spy(MyClass) spyCUT.something = new Bubble(name: "initial") // 给字段设初始值 when: spyCUT.clearSomething() then: spyCUT.something == null } def "test setSomethingExplicitly calls setter with Bubble"() { given: def spyCUT = Spy(MyClass) when: spyCUT.setSomethingExplicitly() then: 1 * spyCUT.setSomething(_ as Bubble) spyCUT.something instanceof Bubble } } class Bubble { String name }
内容的提问来源于stack exchange,提问作者mike rodent
相关产品推荐
相关产品推荐

