Spock框架中能否通过When块赋值在where块使用全局变量?
Spock框架中Where块与When块的执行逻辑及解决方案
核心结论
不能通过When块的赋值在Where块中填充数据。
原因
Spock的测试执行顺序是先解析Where块的参数化矩阵,为每一行参数生成独立的测试迭代,之后才会执行每个迭代对应的Given/When/Then代码块。也就是说,Where块的参数解析逻辑在整个测试方法的业务逻辑(包括When块)之前运行,When块中的赋值根本无法反向影响Where块的参数配置。
解决方案
要实现“调用APIV2获取数据并填充全局变量,供Where块参数化复用”的需求,建议使用setupSpec()方法提前初始化共享变量:
示例代码
class SubscriberSpec extends Specification { // 声明共享变量,@Shared确保在整个测试类中复用 @Shared static String APIV2 @Shared static String Obos @Shared static String Arendal @Shared static String Sparebank @Shared static String Andebu @Shared static String SUBSCRIBER_DETAILS // setupSpec在测试类初始化时执行一次,适合提前调用API获取数据 def setupSpec() { // 调用APIV2接口获取原始数据 APIV2 = callSubscriberApiV2() // 从API返回结果中提取各订阅者详情 Obos = extractObosDetails(APIV2) Arendal = extractArendalDetails(APIV2) Sparebank = extractSparebankDetails(APIV2) Andebu = extractAndebuDetails(APIV2) } def "验证订阅者详情正确性"() { when: SUBSCRIBER_DETAILS = targetDetails // 直接使用Where块传入的参数赋值 then: // 这里添加你的断言逻辑,比如验证SUBSCRIBER_DETAILS的格式/内容 SUBSCRIBER_DETAILS != null SUBSCRIBER_DETAILS.contains(subscriberId) where: subscriberId | targetDetails subscriberIdObos | Obos subscriberIdArendal | Arendal subscriberIdSparebank | Sparebank subscriberIdAndebu | Andebu } // 模拟API调用方法 private String callSubscriberApiV2() { // 实际项目中替换为真实的API调用逻辑 return "API_V2_RESPONSE_DATA" } // 模拟数据提取方法 private String extractObosDetails(String apiResponse) { return "OBOS_SUBSCRIBER_DETAILS" } // 其他数据提取方法同理... }
关键说明
setupSpec()是Spock的生命周期方法,仅在测试类加载时执行一次,适合初始化全局共享的静态/共享变量,比如提前调用外部接口获取测试数据。- Where块的参数只能引用静态变量、常量、无参数/仅用静态参数的方法调用,这些内容在测试类初始化阶段就已确定,才能被Where块正确解析。
内容的提问来源于stack exchange,提问作者Jadran
相关产品推荐
相关产品推荐

