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

@InjectMocks与@Mock测试RequestListServiceImpl报错及必要性咨询

问题根源

你混淆了两个Mockito注解的作用:

  • @Mock 是创建完全模拟的假对象,所有方法都是空实现,默认返回null,必须手动打桩才能指定返回值
  • @InjectMocks 是创建真实的目标类对象,会自动把你声明的@Mock对象注入到它的依赖里,目的就是测试真实业务逻辑

第二个测试报错的核心原因是:你完全不该验证被测试类本身的方法调用,verify方法只能作用于mock对象,你要验证的是service依赖的dao层方法有没有被正确调用。


正确解决方案

第一步:保留@InjectMocks注解

不要把RequestListServiceImpl的注解改成@Mock,你要测试service的真实业务逻辑,就必须用真实的service对象,用@Mock的话你测的都是自己打桩的假逻辑,没有任何测试价值。

第二步:修改testCreateRequest的验证逻辑

把验证service本身的代码删掉,改成验证dao层方法的调用,修改后代码如下:

@Test
public void testCreateRequest() throws Exception {
    // 打桩dao层的getTime方法
    when(requestListDao.getTime(anyString())).thenReturn(0);
    RequestList r = new RequestList();
    r.setCreateName("demo");
    // 调用被测试类的真实方法
    requestListServiceImpl.createRequest(r);
    // 验证dao层的方法被正确调用
    // 验证getTime方法被调用1次,参数为demo
    verify(requestListDao, times(1)).getTime("demo");
    // 捕获传入dao的参数,验证time字段被正确+1
    ArgumentCaptor<RequestList> requestCaptor = ArgumentCaptor.forClass(RequestList.class);
    verify(requestListDao, times(1)).createRequest(requestCaptor.capture());
    Assert.assertEquals(Integer.valueOf(1), requestCaptor.getValue().getTime());
}

常见疑问

@InjectMocks是必须的吗?

不是必须的,你也可以手动new RequestListServiceImpl(),再手动把mock出来的requestListDao通过构造方法或者set方法注入进去,效果和@InjectMocks完全一致,@InjectMocks只是用来简化注入代码的语法糖而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:15:07