Mockito单元测试调用doNothing()触发NullPointerException问题求助
问题分析与解决方案
核心问题梳理
你遇到的错误源于几个关键的代码问题和Mockito使用误区:
- Mockito无法存根真实对象的方法:
@InjectMocks注入的是MyService的真实实例,而非Mockito的Spy/Mock对象,doNothing()对真实对象的方法完全无效。 - static方法的误用:被测类中
createUser是static方法,但测试中却通过实例调用,且Mockito无法直接处理static方法(除非依赖PowerMock,不推荐)。 - 语法与逻辑错误:
user.setName(Jack)中Jack未加引号,属于字符串常量语法错误;- 测试中调用
myService.createUser()未传入User参数,导致被测方法内user为null,触发NullPointerException; createUser是void方法,测试中用assertEquals接收其返回值会直接编译报错。
修正后的代码
被测服务类(MyService)
先将createUser改为实例方法(消除static,这是Mockito可测试的前提):
class MyService { // 去掉static修饰符,改为实例方法并返回User(适配测试断言逻辑) public User createUser(User user) { checkUserBackground(user.getName(), true); return user; } public void checkUserBackground(String name, Boolean newUser) { // 原有业务逻辑 } }
测试类(MyServiceTest)
使用@Spy创建可存根的真实对象包装类,替代@InjectMocks:
@ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) class MyServiceTest { // @Spy创建真实对象的Spy包装,支持存根部分方法 @Spy private MyService myService; @Test void testCreateUser() { User user = new User(); user.setAge(25); user.setName("Jack"); // 修正:字符串常量加引号 // 对Spy对象的checkUserBackground方法进行存根 Mockito.doNothing().when(myService).checkUserBackground(user.getName(), true); // 调用实例方法并传入User参数 User result = myService.createUser(user); assertEquals("Jack", result.getName()); } }
关键说明
- @Spy的作用:创建真实对象的代理类,未存根的方法会执行真实逻辑,存根的方法会按Mockito配置执行(比如这里的
doNothing()),完美适配你需要存根内部方法的场景。 - static方法的处理:如果业务上必须保留
createUser为static方法,需要引入PowerMock扩展,但这会增加测试复杂度,建议优先重构为实例方法,更符合面向对象设计和可测试性要求。 - 参数传递:必须确保调用
createUser时传入有效的User对象,避免空指针异常。
内容的提问来源于stack exchange,提问作者purplewind
相关产品推荐
相关产品推荐

