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

如何用Mockito Mock链式调用Object.getMap().get(key)及Bean类类似场景?

解决Mockito链式调用Mock的问题

在Mockito中处理链式调用(比如object.getMap().get(key)这种嵌套调用),核心是分层Mock每一步返回的对象,不能直接跳过中间层去Mock最内层的方法。我来帮你拆解正确的实现方式,以及分析你之前报错的原因:

一、正确实现两种场景的Mock

场景1:object.getMap().get("String_Key_to_return_Object")

假设getMap()返回的是标准的java.util.Map<String, TargetObject>,步骤如下:

  1. Mock中间的Map对象
  2. 让外层对象的getMap()返回这个Mock的Map
  3. 最后Mock Map的get()方法返回目标对象

代码示例:

// 1. 准备目标对象(你要返回的Object)
TargetObject targetObj = new TargetObject();

// 2. Mock Map对象
Map<String, TargetObject> mockMap = mock(Map.class);

// 3. Mock外层对象(假设是YourObject类型)
YourObject mockObject = mock(YourObject.class);

// 4. 设置外层对象的getMap()返回Mock的Map
when(mockObject.getMap()).thenReturn(mockMap);

// 5. 设置Mock Map的get()方法返回目标对象
when(mockMap.get("String_Key_to_return_Object")).thenReturn(targetObj);

场景2:ObjectOfBeanClass.getMapObject().get("String_Key_To_Return_Object")

如果getMapObject()返回的是自定义的MapObject类(而非标准Map),思路完全一致:

// 1. 准备目标对象
TargetObject targetObj = new TargetObject();

// 2. Mock自定义的MapObject
MapObject mockMapObject = mock(MapObject.class);

// 3. Mock你的Bean对象
BeanClass mockBean = mock(BeanClass.class);

// 4. 设置Bean的getMapObject()返回Mock的MapObject
when(mockBean.getMapObject()).thenReturn(mockMapObject);

// 5. 设置Mock MapObject的get()方法返回目标对象
when(mockMapObject.get("String_Key_To_Return_Object")).thenReturn(targetObj);

如果你的ObjectOfBeanClass是真实对象(而非完全Mock的对象),需要用spy来部分Mock:

// 1. 真实Bean对象
BeanClass realBean = new BeanClass();
// 2. 创建spy包装真实对象
BeanClass spyBean = spy(realBean);

// 3. Mock MapObject
MapObject mockMapObject = mock(MapObject.class);

// 4. 用doReturn指定spyBean的getMapObject()返回Mock对象(避免调用真实方法)
doReturn(mockMapObject).when(spyBean).getMapObject();

// 5. Mock get()方法
when(mockMapObject.get("String_Key_To_Return_Object")).thenReturn(targetObj);

二、分析你之前的报错原因

错误1:when(ObjectOfBeanClass.getMapObject().get("...")).thenReturn(Object);

当你直接写这段代码时,如果ObjectOfBeanClass是真实对象,getMapObject()会调用真实方法,返回的可能是null或者未初始化的MapObject,Mockito无法拦截这个链式调用——它需要先MockgetMapObject()返回的中间对象,才能继续Mock内层的get()方法。

如果ObjectOfBeanClass是Mock对象,但你没有先设置getMapObject()的返回值,那么它默认返回null,调用get()时自然会抛出空指针或类型不匹配的异常。

错误2:doReturn(Object).when(ObjectOfBeanClass.getMapObject()).thenReturn(Object);

这段代码的语法完全错误!Mockito的doReturn正确用法是:

doReturn(要返回的值).when(Mock/Spy对象).方法名(参数);

你在when()里传入的是ObjectOfBeanClass.getMapObject()的调用结果(而非Mock对象),还额外加了thenReturn,导致Stubbing流程未完成,所以抛出UnfinishedStubbingException。

核心总结

处理链式调用的关键是从外到内逐层Mock:先Mock最外层对象,设置它返回中间层的Mock对象,再Mock中间层对象返回最终目标值,不能一步到位跳过中间层。

内容的提问来源于stack exchange,提问作者mubarak khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:16:30