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

Mock静态PreparedStatement方法测试CRUD时遇空指针异常求助

解决PowerMock静态Mock失效、原方法仍被执行的问题

我来帮你梳理下这个问题的解决思路——你遇到的其实是PowerMock和Mockito版本不兼容导致的静态Mock失效问题,咱们一步步拆解:

问题场景回顾

你在测试数据库操作的deleteFoo方法时,想完全Stub掉StatementUtility的静态方法getFoo,避免执行原方法里创建PreparedStatement的逻辑,但不管换Mockito还是BDDMockito,调整参数匹配器、Mock Connection,都还是触发了原方法,抛出空指针异常。用的依赖是JUnit 4.12、Mockito 2.13.0、PowerMock 1.7.1。

核心原因:版本不兼容

这里的关键坑是PowerMock 1.7.x只兼容Mockito 1.x系列,根本不支持Mockito 2.x。你用的Mockito 2.13.0超出了PowerMock 1.7.1的兼容范围,导致静态Mock的拦截逻辑完全失效,原方法自然会被执行,进而引发空指针。

解决方案

方案1:降级Mockito到1.x(你已经验证有效)

把Mockito换成1.x的稳定版本,比如mockito-all:1.10.19,保持PowerMock 1.7.1不变,对应的PowerMock-Mockito依赖用powermock-mockito-1.7.1-full.jar,这样版本匹配上,静态Mock就能正常工作了。

方案2:升级PowerMock适配Mockito 2.x

如果不想降级Mockito,就把PowerMock升到支持Mockito 2.x的版本,比如用powermock-module-junit4:2.0.9 + powermock-api-mockito2:2.0.9,搭配Mockito 2.28.2这类兼容的2.x版本,这样也能解决版本冲突问题。

正确的静态Mock写法(以兼容版本为例)

顺便给你贴个标准的写法,确保配置和代码都没问题:

@RunWith(PowerMockRunner.class)
@PrepareForTest(StatementUtility.class) // 必须指定要Mock的静态类,这步不能忘!
public class DBConnectionBTBAdminTest {

    @Test
    public void deleteTest() throws SQLException {
        List<String> testInput = new ArrayList<>();
        testInput.add("hello");
        testInput.add("World");

        // 先Mock Connection和PreparedStatement,避免空指针
        Connection mockConn = PowerMockito.mock(Connection.class);
        PreparedStatement mockPstmt = PowerMockito.mock(PreparedStatement.class);
        PowerMockito.when(mockConn.prepareStatement(anyString())).thenReturn(mockPstmt);

        // 静态Mock StatementUtility.getFoo方法
        PowerMockito.mockStatic(StatementUtility.class);
        BDDMockito.given(StatementUtility.getFoo(anyString(), eq(mockConn))).willReturn(mockPstmt);

        // 调用待测试方法
        SomeClass.deleteCategory(testInput, new String[]{});

        // 可选:验证静态方法是否被调用
        PowerMockito.verifyStatic(StatementUtility.class);
        StatementUtility.getFoo(anyString(), eq(mockConn));
    }
}

几个关键注意点

  • @PrepareForTest必须加对:一定要包含你要Mock的静态类StatementUtility,不然PowerMock没法拦截静态方法调用。
  • 参数匹配器要一致:Mock时用的匹配器(比如anyString()、eq(mockConn))要和实际调用的参数类型、值匹配,不然会因为匹配失败走原方法逻辑。
  • 先Mock依赖对象:先把Connection、PreparedStatement这些依赖Mock好,再作为静态方法的返回值,避免空指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:22:06