Spock框架Groovy测试where块引用then块变量报错问题咨询
问题解答
根本原因
Spock 框架中 where 块的处理优先级远高于测试执行逻辑:
where块属于测试用例预处理阶段,会在所有given/when/then步骤执行前完成解析,用来生成全部参数化测试用例then块属于测试用例执行阶段,是单条用例运行时才会触发的逻辑,你在then块中定义的assertvalue1、assertvalue2变量,where块处理时还未初始化,自然会抛出找不到属性的错误。
正确实现方案
根据你的使用场景,可以选择以下符合 Spock 规范的写法:
方案1:全局定义固定断言值
如果断言值是测试类通用的固定值,直接定义在类的全局作用域即可:
class YourTestSpec extends Specification { // 全局定义固定值,where块可直接读取 def assertvalue1 = "1" def assertvalue2 = "2" def "Groovy Test"() { given: def primerEndpoint = new RESTClient( 'http://localhost:8080/' ) primerEndpoint.headers['username'] = "username" when: def resp = primerEndpoint.get( path: 'testme/') then: assert resp.data[0] == value1 where: value1 | value2 assertvalue1 | assertvalue2 } }
方案2:在where块内定义变量
如果断言值仅给当前测试用例的参数化使用,直接在 where 块内赋值更简洁:
def "Groovy Test"() { given: def primerEndpoint = new RESTClient( 'http://localhost:8080/' ) primerEndpoint.headers['username'] = "username" when: def resp = primerEndpoint.get( path: 'testme/') then: assert resp.data[0] == value1 where: // 直接在where块内定义变量,可用于后续参数化赋值 assertvalue1 = "1" assertvalue2 = "2" value1 = assertvalue1 value2 = assertvalue2 }
如果有多组测试用例,也可以结合固定值和多组参数使用:
where: baseValue1 = "1" baseValue2 = "2" value1 | value2 baseValue1 | baseValue2 baseValue1+"0" | baseValue2+"0"
方案3:动态断言无需使用where块
如果你需要根据接口返回结果动态计算断言值,不需要用到参数化能力的话,直接去掉 where 块,在 then 块内完成断言即可。
内容的提问来源于stack exchange,提问作者Flenters
相关产品推荐
相关产品推荐

