Spock单元测试then块条件判断未按预期执行问题咨询
问题根因
该异常行为由Spock框架编译期的AST(抽象语法树)转换规则导致,并非then块整体提前执行,是交互存根声明的特殊处理逻辑触发了部分分支代码的提前运行。
Spock对then块中mock对象.方法调用 >> 返回值格式的交互存根声明有特殊处理逻辑:所有交互存根必须在when块执行前生效,才能保证when块调用对应方法时命中预设返回值。因此Spock在编译阶段会扫描then块的全部代码,只要检测到交互存根语法,就会将包含该存根的上层代码块提前到when块之前执行。
失败用例触发逻辑
第一个用例中,交互存根it.call() >> ""放在if-else的else分支内,Spock扫描到存根后,会把整个if-else结构提前到when块之前执行:
- 此时
result还停留在given块初始化的0 - 分支判断
if(true)命中,执行assert result == 1直接抛出断言失败 when块完全没有得到执行机会,因此不会打印对应的日志
成功用例运行逻辑
第二个用例中,交互存根放在独立的if(false)分支内,Spock只会把这个独立的if(false)代码块提前到when之前执行:
- 提前执行的
if(false)判断不成立,不会触发任何逻辑,也不会影响另一个独立的if(true)分支 when块正常执行,result被赋值为1- 之后执行
if(true)分支的断言,验证通过
规避方案
- 所有Mock的交互存根定义统一放在
given块中,不要出现在then块的条件分支里 - 若确实需要在
then块做条件判断,不要把断言逻辑和交互存根逻辑放在同一个if-else结构内 - 动态存根可以使用Spock的显式API定义,避免
>>语法糖触发提前转换
内容的提问来源于stack exchange,提问作者haridsv
相关产品推荐
相关产品推荐

