无法两次使用Mocked RestTemplate:多请求体匹配响应失败
解决Mock RestTemplate多请求体匹配失败的问题
问题根源
你遇到的问题是因为Mockito默认用equals()方法匹配参数,如果你的请求体类(比如requestBody1/2所属的类)没正确实现equals和hashCode,Mockito会判定两次调用的请求体不匹配,导致第二个when规则无法生效。单次调用时因为只有一条匹配规则,所以能正常工作。
解决方案
1. 给请求体类正确实现equals和hashCode
如果是自定义的请求体实体类,确保它的equals和hashCode方法能正确比较对象内容:
- 用Lombok注解自动生成(最省事):
@Data public class RequestBody { private String keyField; private Integer valueField; // 其他业务字段 } - 或者手动实现:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RequestBody that = (RequestBody) o; return Objects.equals(keyField, that.keyField) && Objects.equals(valueField, that.valueField); } @Override public int hashCode() { return Objects.hash(keyField, valueField); }
2. 用Mockito参数匹配器自定义匹配逻辑
如果不想修改实体类,可以用ArgumentMatchers.argThat()指定自定义匹配规则:
import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; // 匹配requestBody1的规则 when(dlfRestTemplate.postForObject( eq("url"), argThat(req -> req.getKeyField().equals(requestBody1.getKeyField())), eq(ResponseBdy.class) )).thenReturn(response1); // 匹配requestBody2的规则 when(dlfRestTemplate.postForObject( eq("url"), argThat(req -> req.getKeyField().equals(requestBody2.getKeyField())), eq(ResponseBdy.class) )).thenReturn(response2);
注意:使用参数匹配器时,所有参数都必须用匹配器(比如eq()),不能混合字面量和匹配器。
3. 调试小技巧
如果还是不确定问题在哪,可以在测试代码里打印请求体的equals结果,确认是否匹配:
// 获取实际传入RestTemplate的请求体 RequestBody actualReq = ...; System.out.println("requestBody1匹配结果:" + requestBody1.equals(actualReq)); System.out.println("requestBody2匹配结果:" + requestBody2.equals(actualReq));
内容的提问来源于stack exchange,提问作者aksh_18
相关产品推荐
相关产品推荐

