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
相关产品推荐
相关产品推荐

