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

Mockito存根测试问题:newUser.getId()引发空指针异常求助

Mockito存根测试NPE问题解决思路

先揪出核心问题

  • 依赖未Mock:测试类里没给业务类MyService中的newService添加@Mock注解,@InjectMocks无法注入未被Mock的对象,导致myService里的newService为null,调用checkBackground直接触发空指针异常。
  • 参数匹配存在隐患:就算newService被Mock,存根时直接传userRes.getId()当参数,若业务代码中newUser.getId()返回的字符串实例和测试里的不是同一个(比如User的getId方法返回新字符串),Mockito默认按引用匹配,存根会失效,也可能引发异常。

一步步修复

1. 给依赖添加Mock注解

在测试类中补上newService的Mock声明,注意类名要和业务类里的字段类型一致:

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class MyServiceTest {

    @InjectMocks
    private MyService myService;

    @Mock // 必须添加,将newService转为Mock对象
    private NewService newService; // 这里的NewService要和业务类里的newService类型对应

    @Test
    void testMyStuff() {
        User user = new User();
        user.setId("444");
        
        User userRes = new User();
        userRes.setId("444");

        try(MockedStatic<UserDao> userDao = mockStatic(UserDao.class)) {
            userDao.when(() -> UserDao.putUserData(user)).thenReturn(userRes);
            // 用eq()匹配参数值,忽略引用是否相同
            when(newService.checkBackground(eq("444"), eq(false))).thenReturn("test");
            
            // 必须执行业务方法,原测试遗漏了这一步
            myService.grantAccess();
            
            // 可选:验证方法确实被调用
            verify(newService).checkBackground(eq("444"), eq(false));
        }
    }
}

2. 用参数匹配器替代直接传值

把存根里的参数换成eq()包裹,比如eq(userRes.getId())或者直接eq("444"),让Mockito按值匹配参数,而非严格的引用相等,避免因字符串实例不同导致存根失效。

3. (可选)完善User类的equals/hashCode

如果后续需要基于User对象做参数匹配,确保User类正确实现了equals和hashCode方法,不过本次是匹配ID字符串,这一步非必须。

额外提醒

  • 要导入Mockito相关类,比如org.mockito.Mock、org.mockito.Mockito.*、org.mockito.ArgumentMatchers.eq等。
  • 原测试代码未调用myService.grantAccess(),等于没触发业务逻辑,必须补上这一步才能完成测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:15:34