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
相关产品推荐
相关产品推荐

