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

When/thenReturn未映射到Mock Bean问题排查

问题分析:Mockito的when/thenReturn未匹配导致返回null

嘿,我一眼就看出问题出在哪了——Mockito默认是按对象引用来匹配方法调用的,而你测试里的情况刚好踩了这个坑!

你在测试中创建了userEntity对象,然后写了:

when(userService.update("666", userEntity)).thenReturn(userEntity);

但实际控制器里接收到的UserDTO对象,是Spring MVC从请求体的JSON字符串反序列化出来的全新实例,和你测试里创建的userEntity不是同一个对象(引用不同)。Mockito会认为这两个调用的参数不匹配,所以就返回了默认的null。

解决方案:使用Mockito参数匹配器

你有两种常见的解决方式,根据你的需求选:

1. 放宽参数匹配(最简单)

如果不需要严格验证传入的UserDTO实例,只是想让Mock的userService.update返回预期值,可以用any()匹配器:

// 别忘了导入静态匹配器:import static org.mockito.ArgumentMatchers.any;
@Test
public void testUpdate() throws Exception {
    UserDTO userEntity = createUser("666", 66, "User_6");
    // 修改参数匹配逻辑,匹配任意String类型的id和任意UserDTO实例
    when(userService.update(any(String.class), any(UserDTO.class))).thenReturn(userEntity);

    this.mockMvc.perform(put(UsersController.URL + "/666")
            .contentType(MediaType.APPLICATION_JSON)
            .content(jacksonMapper.writeValueAsString(userEntity)))
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(status().isOk())
            // 额外验证返回内容是否符合预期
            .andExpect(content().json(jacksonMapper.writeValueAsString(userEntity)));
}

2. 按属性匹配(更严格)

如果你想确保传入的UserDTO属性和你定义的一致,可以用refEq()匹配器(它会对比对象的属性值,而不是引用):

// 导入:import static org.mockito.ArgumentMatchers.eq;
// 导入:import static org.mockito.ArgumentMatchers.refEq;
@Test
public void testUpdate() throws Exception {
    UserDTO userEntity = createUser("666", 66, "User_6");
    // 匹配id为"666",且属性和userEntity一致的UserDTO
    when(userService.update(eq("666"), refEq(userEntity))).thenReturn(userEntity);

    this.mockMvc.perform(put(UsersController.URL + "/666")
            .contentType(MediaType.APPLICATION_JSON)
            .content(jacksonMapper.writeValueAsString(userEntity)))
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(status().isOk());
}

额外小优化

你的测试类里有个多余的@MockBean private UserDTO userDto;——UserDTO是普通的模型类,不需要Mock,直接创建实例就行,把这个删掉避免混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:59:03