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

Spock测试报错:Long类型参数被识别为数组,找不到匹配的闭包方法

问题根因

你遇到的报错是Spock Mock语法使用错误导致的,具体原因有两个:

  • 闭包参数类型声明错误:你在then块中为productRepository.getByIdOrThrow(_)定义的响应闭包,错误声明入参为Product类型,但getByIdOrThrow方法的实际入参是Long类型的商品ID。Spock调用响应闭包时,会将Mock方法收到的所有入参打包为List传入,你声明的入参类型和实际传入的List(内部元素为你传递的Long类型ID)不匹配,因此抛出了参数类型不匹配的异常。
  • 打桩与交互校验逻辑混淆:given块用于提前定义Mock方法的返回值,then块用于校验方法的交互行为,你在then块重复定义Mock方法的返回逻辑属于语法误用。
修正后的测试代码

如果你的测试目标是校验getProductById方法正确调用DAO层接口、且返回结果符合预期,正确写法如下:

def "should get product by id"() {
        given:
        Product expectedProduct = getBeer(UPLOADED_FILE_DETAILS_IMG)
        Long targetId = expectedProduct.id().get()

        when:
        Product actualResult = productApplicationService.getProductById(targetId)

        then:
        // 同时完成:校验调用次数为1、入参正确、打桩返回值
        1 * productRepository.getByIdOrThrow(targetId) >> expectedProduct
        // 校验返回结果符合预期
        actualResult.name() == expectedProduct.name()
        actualResult.description() == expectedProduct.description()
        actualResult.category() == expectedProduct.category()
        actualResult.price() == expectedProduct.price()
        actualResult.creationDate() == expectedProduct.creationDate()
}
补充说明

如果你确实需要在响应闭包中处理入参,正确的写法应该匹配Mock方法的入参类型:

// getByIdOrThrow入参为Long类型,闭包参数对应声明为Long即可
productRepository.getByIdOrThrow(_) >> { Long id ->
    // 在这里可以根据id返回不同的结果
    return id == targetId ? expectedProduct : null
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:27:05