You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spock中where子句调用静态方法时测试发现失败问题求助

Spock框架where子句调用静态方法导致测试发现失败的解决思路

问题描述

在Spock框架中,直接在where子句使用内联数据表格编写测试用例时,测试可正常通过;但将数据表格提取到静态方法并在where子句中调用该方法后,出现测试发现失败的VerifyError错误。

正常通过的测试代码

@Unroll
def "max of #a and #b gives #c"() {
    expect:
    Math.max(a, b) == c
    where:
    [a, b, c] << [
            [1, 0, 1],
            [2, 2, 2],
            [4, 5, 5]
    ]
}

调用静态方法的出错代码

@Unroll
def "max of #a and #b gives #c"() {
    expect:
    Math.max(a, b) == c
    where:
    [a, b, c] << dataTable()
}

static def dataTable() {
    return [
            [1, 0, 1],
            [2, 2, 2],
            [4, 5, 5]
    ]
}

错误堆栈信息

org.junit.platform.commons.JUnitException: TestEngine with ID 'spock' failed to discover tests
Caused by: org.junit.platform.commons.JUnitException: MethodSelector [className = 'specs.filters.FiltersPostSpec', methodName = 'max of #a and #b gives #c', methodParameterTypes = ''] resolution failed
Caused by: java.lang.VerifyError: (class: specs/filters/FiltersPostSpec, method: $spock_feature_2_3prov0 signature: ()Ljava/lang/Object;) Illegal target of jump or branch

使用版本

<groovy.version>3.0.9</groovy.version>
<spock-core.version>2.1-groovy-3.0</spock-core.version>
<spock-reports.version>2.3.0-groovy-3.0</spock-reports.version>

解决思路

  • 升级Groovy版本:Groovy 3.0.9存在已知的字节码生成bug,导致Spock动态生成测试代码时出现VerifyError。建议升级到Groovy 3.0.17或更高版本,该版本修复了多个字节码相关问题。
  • 明确静态方法返回类型:将静态方法的返回类型从def改为具体的List<List<Integer>>,避免Groovy动态类型带来的字节码生成歧义:
    static List<List<Integer>> dataTable() {
        return [
                [1, 0, 1],
                [2, 2, 2],
                [4, 5, 5]
        ]
    }
    
  • 升级Spock版本:尝试将Spock Core升级到2.3-groovy-3.0版本,该版本对Groovy 3.x的兼容性更好,修复了多个测试发现阶段的问题。
  • 替代方案:如果上述方法无效,可以改用@Shared变量存储数据表格,在setup()方法中初始化,再在where子句中引用:
    @Shared List<List<Integer>> testData
    
    def setup() {
        testData = [
                [1, 0, 1],
                [2, 2, 2],
                [4, 5, 5]
        ]
    }
    
    @Unroll
    def "max of #a and #b gives #c"() {
        expect:
        Math.max(a, b) == c
        where:
        [a, b, c] << testData
    }
    

内容的提问来源于stack exchange,提问作者amadain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:55:20