mockito 中 when-thenreturn 用于为 mock 对象方法设返回值,需配合 mock() 或 @mock 使用非 final/static/private 实例方法;推荐 doreturn().when().method() 更安全。

在 Mockito 中,when 和 thenReturn 是最常用的组合,用于为 mock 对象的方法调用设置返回值。核心逻辑是:先用 when 声明“当调用哪个方法”,再用 thenReturn 指定“就返回什么值”。注意不能直接对真实对象或未 mock 的对象使用 when,否则会抛出异常。
基本语法结构
when 必须接收一个由 mock() 或 @Mock 创建的 mock 对象的方法调用(即 stubbing 调用),不能是普通对象或静态方法。调用必须是“可被拦截”的——也就是非 final、非 static、非 private 的实例方法。
- ✅ 正确写法:
when(mockService.getData()).thenReturn("test") - ❌ 错误写法:
when(realService.getData()).thenReturn("test")(真实对象不支持) - ❌ 错误写法:
when(SomeUtil.staticMethod()).thenReturn(...)(静态方法需用Mockito.mockStatic())
常见使用场景
适用于需要隔离依赖、控制返回结果的单元测试,比如模拟数据库查询、远程接口响应、工具类计算结果等。
- 模拟简单返回值:
when(userDao.findById(123)).thenReturn(new User("Alice")) - 模拟空值:
when(userDao.findById(999)).thenReturn(null) - 模拟集合:
when(orderService.listByUserId(100)).thenReturn(Arrays.asList(order1, order2)) - 多次调用不同返回值:
when(counter.next()).thenReturn(1).thenReturn(2).thenReturn(3)(依次返回)
注意事项和易错点
这个组合看似简单,但几个细节容易导致测试失败或行为不符合预期:
-
参数匹配要一致:如果方法重载或含多个参数,确保
when中传入的参数和实际调用时一致;建议用eq()、anyString()等匹配器提升可读性和健壮性 -
void 方法不能用 thenReturn:对于返回 void 的方法(如
save(User)),应改用doNothing()、doThrow()或doAnswer() -
不能嵌套 when:像
when(mock.doX(when(...).thenReturn(...)))是非法的,会导致UnfinishedStubbingException -
mock 对象需正确初始化:使用
@Mock时记得配合@ExtendWith(MockitoExtension.class)(JUnit 5)或@RunWith(MockitoJUnitRunner.class)(JUnit 4)
替代写法(更现代推荐)
从 Mockito 3.4.0 开始,推荐优先使用 doReturn(...).when(mock).method() 形式,尤其在处理 spy 对象或避免“意外真实调用”时更安全:
- 传统写法:
when(list.get(0)).thenReturn("first") - 推荐写法:
doReturn("first").when(list).get(0) - 优势:不会触发
list.get(0)的真实逻辑(比如 list 是 spy 且 get(0) 报 NPE,传统写法会崩)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











