如何为Json.mapper().constructType(type)编写Mockito.when()存根并解决报错?
问题:Mockito存根Json.mapper().constructType()时出现MissingMethodInvocationException
场景代码
待测试的resolveProperty方法:
@Override public Property resolveProperty(Type type, ModelConverterContext context, Annotation[] annotations, Iterator<ModelConverter> chain) { JavaType jType = Json.mapper().constructType(type); ... }
尝试编写的存根代码:
when(Json.mapper()).thenReturn(objectMapper); when(objectMapper.constructType(type)).thenReturn(jType);
报错信息
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'. For example:when(mock.getArticles()).thenReturn(articles);Also, this error might show up because:
- you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified.
- inside when() you don't call method on mock but on some other object.
- the parent of the mocked class is not public. It is a limitation of the mock engine.
解决方案
核心原因
报错本质是Json.mapper()为静态方法(或final实例方法),Mockito默认无法对这类方法存根——when()要求参数必须是mock对象的方法调用。
方案1:使用Mockito静态方法Mock(Mockito 3.4+)
若使用Mockito 3.4及以上版本,可通过MockedStatic实现静态方法的mock:
// 创建ObjectMapper的mock实例 ObjectMapper mockObjectMapper = mock(ObjectMapper.class); when(mockObjectMapper.constructType(type)).thenReturn(jType); // 用try-with-resources包裹静态mock,确保测试后自动清理 try (MockedStatic<Json> mockedJson = mockStatic(Json.class)) { mockedJson.when(Json::mapper).thenReturn(mockObjectMapper); // 执行你的测试逻辑 }
方案2:重构代码,依赖注入ObjectMapper(推荐)
避免直接依赖静态方法,改为构造函数注入ObjectMapper,降低代码耦合度:
- 修改目标类,注入
ObjectMapper:
public class YourModelConverter implements ModelConverter { private final ObjectMapper objectMapper; // 构造函数注入 public YourModelConverter(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } @Override public Property resolveProperty(Type type, ModelConverterContext context, Annotation[] annotations, Iterator<ModelConverter> chain) { JavaType jType = objectMapper.constructType(type); // 原有业务逻辑 } }
- 测试时直接mock并注入:
// 创建mock的ObjectMapper ObjectMapper mockObjectMapper = mock(ObjectMapper.class); when(mockObjectMapper.constructType(type)).thenReturn(jType); // 初始化测试对象,注入mock实例 YourModelConverter converter = new YourModelConverter(mockObjectMapper); // 执行测试逻辑
额外注意事项
- 若
Json.mapper()是final实例方法,需引入mockito-inline依赖,让Mockito支持final方法的mock。 - 确保所有存根对象都是通过
mock()方法创建的mock实例,而非真实对象。
内容的提问来源于stack exchange,提问作者Mohitkumar Shah
相关产品推荐
相关产品推荐

