Mockito存根时抛出NullInsteadOfMockException异常的原因排查
Mockito NullInsteadOfMockException 问题排查与解决
可能的原因及修复方案
1. Mock对象初始化顺序错误
这是最常见的原因:你在初始化测试对象sut之后才调用MockitoAnnotations.openMocks(this),导致注入的template还是null。
- 错误写法:
@Mock private NamedParameterJdbcTemplate template; private PointIssuanceLookupDao sut; @Before public void setUp() { sut = new PointIssuanceLookupDao(template); // 此时template未被Mock初始化,为null MockitoAnnotations.openMocks(this); } - 正确写法:
@Mock private NamedParameterJdbcTemplate template; private PointIssuanceLookupDao sut; @Before public void setUp() { MockitoAnnotations.openMocks(this); // 先初始化所有@Mock注解的对象 sut = new PointIssuanceLookupDao(template); // 再用已初始化的Mock创建测试对象 }
2. 注解包导入错误
确保你用的是Mockito的@Mock注解,而非其他框架(比如Spring)的同名注解。检查导入语句:
- 正确导入:
import org.mockito.Mock;
3. JUnit版本适配问题
如果使用JUnit 5,建议直接用MockitoExtension替代手动调用openMocks,避免初始化顺序问题:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class PointIssuanceLookupDaoTest { @Mock private NamedParameterJdbcTemplate template; private PointIssuanceLookupDao sut; @BeforeEach public void setUp() { sut = new PointIssuanceLookupDao(template); } }
4. 存根代码引用对象错误
检查存根语句,确保直接使用template对象而非sut内部的引用。比如不要写when(sut.getJdbcTemplate().query(...))(如果sut没有暴露正确的getter,会返回null),直接用:
when(template.query(anyString(), anyMap(), anyRowMapper())).thenReturn(yourTestData);
核心总结
本质问题是Mock对象未完成初始化就被注入到测试对象中,导致存根时template为null。只要保证openMocks(或MockitoExtension初始化)在sut创建之前执行,就能解决绝大多数这类问题。
内容的提问来源于stack exchange,提问作者techie11
相关产品推荐
相关产品推荐

