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

JUnit+MockMvc测试中BDDMockito模拟Service返回值失败求助

问题解答:JUnit测试中用BDDMockito.given()Mock Service方法的可行性及问题修复

当然可以用BDDMockito.given()来设置Controller依赖的Service方法返回值,你的测试失败是因为几个关键细节没处理好,导致Mock的Service方法没有生效,最终返回null引发NPE。下面一步步分析问题并给出修复方案:

核心问题分析

你遇到的NullPointerException是因为:

  1. MockMvc未正确初始化:你的测试类里声明了restUserSystemMockMvc但没有赋值,发送请求的环节根本没正确关联到Spring上下文里的Controller,请求无法触达Mock的Service所在的上下文。
  2. Mock参数匹配不精准:你用测试里的userSystemDTO作为given()的参数,但Controller接收的是请求体反序列化后的新DTO对象,和测试里的不是同一个实例,导致Mock的匹配条件不满足,Service方法返回默认的null。
  3. Mock返回的DTO可能存在null属性:如果createNewUserSystemDTO()返回的UserSystemDTO的id为null,Controller里构建URI时调用result.getId()也会触发NPE。

具体修复步骤

1. 正确初始化MockMvc

有两种方式可以解决这个问题:

  • 方式一:直接注入MockMvc
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SecurityBeanOverrideConfiguration.class, AccountApp.class})
public class UserSystemResourceIntTest {
    @MockBean
    private UserSystemService userSystemServiceMock;
    // 直接注入MockMvc
    @Autowired
    private MockMvc restUserSystemMockMvc;
    // ... 其他代码不变
}
  • 方式二:在@Before方法中手动构建
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SecurityBeanOverrideConfiguration.class, AccountApp.class})
public class UserSystemResourceIntTest {
    @MockBean
    private UserSystemService userSystemServiceMock;
    private MockMvc restUserSystemMockMvc;
    @Autowired
    private WebApplicationContext webApplicationContext;
    private UserSystem userSystem;

    @Before
    public void initTest() {
        userSystem = createEntity(em);
        // 初始化MockMvc
        restUserSystemMockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
    // ... 其他代码不变
}

2. 修正Mock的参数匹配逻辑

把精准匹配换成宽松匹配,确保任何UserSystemDTO类型的参数都能触发Mock返回值:

// 替换原来的given语句
given(userSystemServiceMock.newAccount(any(UserSystemDTO.class))).willReturn(createNewUserSystemDTO());

注意要导入org.mockito.ArgumentMatchers.any这个静态方法。

3. 确保Mock返回的DTO属性完整

检查createNewUserSystemDTO()方法,确保返回的UserSystemDTO的id不为null,比如给它设置一个有效值:

private static UserSystemDTO createNewUserSystemDTO() {
    UserSystemDTO newUserSystemDTO = new UserSystemDTO(
        1L, // 这里设置一个非null的id值
        DEFAULT_NAME,
        DEFAULT_EMAIL,
        DEFAULT_PASSWORD,
        DEFAULT_PHONE,
        DEFAULT_PHONE,
        DEFAULT_DOCUMENT_TYPE,
        DEFAULT_GENDER,
        DEFAULT_LANG_KEY,
        null, null, null, null);
    return newUserSystemDTO;
}

验证修复后的流程

完成上述修改后,测试的执行逻辑会变成:

  1. Spring上下文启动,@MockBean的userSystemServiceMock替换掉原有的UserSystemService实例
  2. MockMvc正确初始化,能将请求转发到UserSystemResource
  3. 发送POST请求时,Controller调用userSystemServiceMock.newAccount(),因为参数匹配成功,返回你预设的UserSystemDTO
  4. Controller正常构建响应,返回201状态码,测试通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:27:58