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

Spock Mock ProductDecorator无返回数据问题求助

问题解决:Spock Mock参数匹配失效导致无返回

核心原因分析

你遇到的Mock不生效问题,本质是Spock的参数匹配逻辑与对象/集合的相等性校验不匹配:

  • Spock默认使用对象的equals()方法校验参数是否匹配,但你的Product/ProductDetail类因Lombok注解使用不规范,导致equals()未正确仅基于productCode生成;
  • 即使对象的equals()正确,List参数的匹配要求实例完全相等(或元素顺序、内容全匹配),若测试中传入的List与Mock设置的List不是同一实例/元素顺序不同,也会匹配失败。

分步解决方案

1. 修复Lombok注解,确保对象相等性仅基于productCode

你只添加了@EqualsAndHashCode.Include,但未开启onlyExplicitlyIncluded = true,Lombok默认会把所有字段纳入equals()/hashCode()计算,导致即使productCode相同,其他字段不同时对象仍不相等。修正代码:

Product类

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(onlyExplicitlyIncluded = true)
class Product {
    String name;
    @EqualsAndHashCode.Include
    String productCode;
    String category;
    Double price;

    String getProductCode() {
        return productCode;
    }

    public Product addDetail(String category, Double price) {
        this.category = category;
        this.price = price;
        return this;
    }
}

ProductDetail类

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class ProductDetail {
    @EqualsAndHashCode.Include
    String productCode;
    String category;
    Double price;

    public String getProductCode() {
        return productCode;
    }
}

2. 调整Spock Mock的参数匹配策略

如果测试中传入的List与Mock设置的List不是同一实例,即使内容相同,默认匹配也会失败。此时需使用Spock参数匹配器来匹配集合内容,而非实例:

方式一:匹配任意List参数(快速验证)

如果不需要精确校验参数内容,直接匹配任意List<Product>和List<ProductDetail>:

productDecorator.addProductFeature(_ as List<Product>, _ as List<ProductDetail>) >> [products[0]]

方式二:精确匹配集合内容(推荐用于严谨测试)

通过闭包校验集合中每个元素的productCode是否符合预期:

// 假设测试用的productCode是"TEST_CODE"
productDecorator.addProductFeature(
    { List<Product> list -> list.every { it.productCode == "TEST_CODE" } },
    { List<ProductDetail> list -> list.every { it.productCode == "TEST_CODE" } }
) >> [products[0]]

方式三:使用Hamcrest匹配器匹配集合

借助Spock集成的Hamcrest匹配器,校验集合包含指定元素:

import static spock.util.matcher.HamcrestMatchers.containsAll

productDecorator.addProductFeature(containsAll(products[0]), containsAll(productDetailList)) >> [products[0]]

3. 额外排查点

  • 确认测试中调用addProductFeature时传入的参数类型与Mock方法签名完全一致;
  • 检查getProducts()/getProductDetails()生成的对象是否确实有匹配的productCode;
  • 若使用Spring等框架,确保Mock对象已正确注入到测试类中,而非使用了真实实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 09:43:26