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

为何使用Mockito doAnswer修改方法参数后,真实方法仍用原参数?

问题原因及解决方案

为什么修改invocation.getArguments()不生效?

Mockito的invocation.getArguments()返回的是方法调用参数的副本数组,不是传给真实方法的原始参数引用。当你调用reportBuilder.retrieveReport(Report.DEFAULT_ROW_SIZE)时,参数值已经被传递到方法调用的栈帧中,修改副本数组里的值根本不会影响真实方法接收到的参数,所以callRealMethod()还是会用原始的Report.DEFAULT_ROW_SIZE来执行。

正确的解决方式

根据你是否需要保留真实方法的逻辑,有两种处理方案:

方案1:直接返回测试用的Report(无需真实方法逻辑)

如果只是需要替换参数后的结果,不需要执行真实方法的逻辑,直接存根返回模拟对象即可:

int testSize = 5;
// 构建你的测试用Report对象
Report mockReport = new Report(); 
when(reportBuilder.retrieveReport(anyInt())).thenReturn(mockReport);

方案2:必须调用真实方法,替换参数执行

如果你需要执行真实方法的逻辑,但要传入自定义参数,不要用invocation.callRealMethod(),而是手动调用spy对象的真实方法并传入新参数:

int testSize = 5;
doAnswer(invocation -> {
    // 获取当前的spy对象,手动调用真实方法并传入自定义参数
    ReportBuilder spyBuilder = (ReportBuilder) invocation.getMock();
    return spyBuilder.retrieveReport(testSize);
}).when(reportBuilder).retrieveReport(anyInt());

或者更直接的方式(如果spy对象在当前作用域可见):

int testSize = 5;
doAnswer(invocation -> {
    return reportBuilder.retrieveReport(testSize);
}).when(reportBuilder).retrieveReport(anyInt());

这样就能让真实方法接收你指定的testSize参数执行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:32:14