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

Mockito中thenReturn()与thenAnswer()的区别是什么?

Mockito中thenReturn()与thenAnswer()的核心差异及适用场景

核心差异

二者最本质的区别是返回值的计算时机、上下文获取能力不同:

  • 执行时机不同
    • thenReturn()的参数值是在定义Mock规则阶段就提前计算完成的,不管后续该Mock方法被调用多少次,返回的都是预先生成的固定值。你示例中写的thenReturn(callMethod1(obj)),callMethod1会在写Stub代码的那一刻直接执行,后续Mock方法被调用时不会再重新运行callMethod1的逻辑。
    • thenAnswer()的回调逻辑是每次Mock方法被实际调用时才会执行,每次调用都会重新运行一次回调内的代码,返回值可跟随调用上下文动态变化。
  • 上下文获取能力不同
    • thenReturn()无法拿到当前调用Mock方法时传入的实际参数、调用信息,只能返回提前准备好的固定值。
    • thenAnswer()可以通过回调参数(比如你示例中的val)获取本次调用的所有入参、方法元数据等信息,支持基于实际调用场景做逻辑处理。
  • 性能开销不同
    • thenReturn()直接返回预计算的值,无额外执行开销,性能更好。
    • thenAnswer()每次调用都要执行回调逻辑,开销相对更高。

适用场景

  • 优先使用thenReturn()的场景:
    • 返回值是固定常量,或只需预计算一次就可以复用的静态结果
    • 不需要感知Mock方法的实际调用入参、调用上下文
    • 无动态逻辑需求,追求单元测试执行效率
  • 必须使用thenAnswer()的场景:
    • 返回值需要和本次调用的入参联动,比如需要修改入参对象的字段后再返回
    • 同一个Mock方法被多次调用时需要返回动态变化的结果(简单的顺序多返回值可使用thenReturn(val1, val2)重载,但复杂逻辑仍需thenAnswer)
    • 需要在Mock方法被调用时执行额外的副作用逻辑,比如调用计数、日志打印、触发其他回调等
    • 返回值的计算依赖调用时才能确定的上下文信息

直观示例对比:
假设要MockuserService.save(User user)方法,要求每次调用都把传入的user的id设为自增数值:

// 错误写法:id只会在定义Stub时计算一次,后续所有调用返回的id都是1
long id = 1;
User user = new User();
when(userService.save(any(User.class))).thenReturn(user.setId(id++));

// 正确写法:用thenAnswer实现每次调用动态生成id
AtomicLong idGen = new AtomicLong(1);
when(userService.save(any(User.class))).thenAnswer(invocation -> {
    User inputUser = invocation.getArgument(0);
    inputUser.setId(idGen.getAndIncrement());
    return inputUser;
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 19:57:02