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

JUnit Mockito单元测试ObjectMapper.writeValueAsString返回null

问题原因

@Mock注解生成的是Mockito代理的空实现对象,不会执行ObjectMapper原生的序列化逻辑。所有未手动配置桩(Stub)的方法,调用时会直接返回对应返回类型的默认值:writeValueAsString方法返回值是String类型,默认值就是null,这就是你拿到null的直接原因。

补充说明:从现象判断你的Mock对象已经成功注入到被测服务了——如果注入失败,调用objectMapper.writeValueAsString()时会直接抛空指针异常,不会等到拿返回值才发现异常。另外你代码里用的MockitoAnnotations.initMocks(this)已经被标记废弃,新版本Mockito推荐使用MockitoAnnotations.openMocks(this)替代。

修复方案

根据测试场景选一种方案即可:

  • 方案1:不需要Mock ObjectMapper时直接用真实实例(最常用,适合绝大多数单元测试场景)
    ObjectMapper本身是无外部依赖的序列化工具类,完全不需要Mock,直接实例化真实对象注入被测类即可,原生序列化逻辑会正常执行:

    // 不要加@Mock注解,直接初始化真实的ObjectMapper
    private ObjectMapper objectMapper = new ObjectMapper();
    
    @InjectMocks
    private YourAckService ackService; // 替换成你自己的被测服务类
    
    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }
    

    这种方式下writeValueAsString会正常执行序列化逻辑,返回你预期的{"ID":"123"}字符串。

  • 方案2:必须Mock ObjectMapper时手动配置方法桩
    如果你需要验证ObjectMapper的调用次数、入参是否符合预期,必须给Mock对象配置桩规则,明确指定方法调用的返回值:

    @Mock
    private ObjectMapper objectMapper;
    
    @InjectMocks
    private YourAckService ackService;
    
    @BeforeEach
    public void setUp() throws JsonProcessingException {
        MockitoAnnotations.openMocks(this);
        // 配置桩:传入任意Map调用writeValueAsString时,返回指定的JSON串
        when(objectMapper.writeValueAsString(anyMap())).thenReturn("{\"ID\":\"123\"}");
    }
    
    @Test
    public void testAckSend() throws JsonProcessingException {
        // 执行被测业务逻辑
        ackService.sendAck();
        // 可选:验证方法调用符合预期
        verify(objectMapper, times(1)).writeValueAsString(argThat(map -> "123".equals(map.get("ID"))));
    }
    
  • 方案3:Spring集成测试场景直接注入容器真实Bean
    如果你写的是Spring层集成测试,不需要手动Mock,直接用@SpringBootTest加载应用上下文,把项目中配置的真实ObjectMapper Bean注入即可,不会出现返回null的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:01:29