PowerMockito出现NullPointerException,Dao类模拟错误排查
分析你的NullPointerException问题
你的测试代码触发空指针,主要是三个核心问题导致的,我逐个给你拆解清楚:
1. 未初始化SomeClass实例,还错误调用实例方法
你在测试类里只声明了private SomeClass someClass;但没有给它赋值,还尝试用SomeClass.checkurl("str1", "str2")直接调用——但checkurl是实例方法,不是静态方法!这种写法本身会编译报错,就算忽略编译问题,未初始化的someClass本身就是null,调用方法必然触发空指针。
2. 未将Mock的SomeDao注入到SomeClass实例中
你创建了Mock的SomeDao对象,但SomeClass里的dao字段是通过@Autowired注入的,测试环境下Spring不会自动帮你完成注入,所以someClass里的dao始终是null,调用dao.getValue()的时候自然会抛出空指针。
3. PowerMock注解冗余(非直接原因,但可优化)
你给@PrepareForTest加了SomeClass.class,但这里你不需要MockSomeClass本身,只需要Mock它的依赖SomeDao,所以这个注解可以简化,避免不必要的类准备操作。
修正后的测试代码示例
我把你的测试代码调整成正确版本,关键步骤都加了注释:
@RunWith(PowerMockRunner.class) // 只需要准备要Mock的依赖类SomeDao即可 @PrepareForTest(SomeDao.class) public class TestSomeClass { // 注意你原来的Class写成了小写,这里修正为class private SomeClass someClass; private SomeDao mockDao = PowerMockito.mock(SomeDao.class); // 变量名改成mockDao更清晰 @Before public void setUp() { // 初始化SomeClass实例 someClass = new SomeClass(); // 用PowerMock的Whitebox工具,把mock的Dao注入到SomeClass的私有dao字段中 Whitebox.setInternalState(someClass, "dao", mockDao); } @Test public void test_checkurl() throws Exception { // 设定Mock的Dao调用返回值 PowerMockito.doReturn("Value").when(mockDao).getValue(Mockito.anyString()); // 调用实例的checkurl方法,而不是类的静态方法 someClass.checkurl("str1", "str2"); // 可选:验证Dao的方法是否按预期被调用 Mockito.verify(mockDao).getValue(Mockito.eq("urlType")); } }
额外优化建议
- 如果你的
SomeClass能给dao字段加一个setter方法,就不需要用Whitebox反射注入了,直接调用someClass.setDao(mockDao)会更优雅,也更易维护。 - 如果不需要PowerMock的特殊功能(比如Mock静态方法、私有方法),其实用普通的Mockito就足够Mock
SomeDao,不需要引入PowerMock,测试代码会更轻量。
内容的提问来源于stack exchange,提问作者Akhil Kumar
相关产品推荐
相关产品推荐

