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

如何为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,降低代码耦合度:

  1. 修改目标类,注入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);
        // 原有业务逻辑
    }
}
  1. 测试时直接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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:26:52