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

使用PowerMockito和JUnit如何Mock Java中的JNI本地方法

问题修复方案

错误原因

  • 你在测试用例中mock的A实例没有被注入到Util.test()方法中,Util.test()每次执行都会自行new一个全新的A实例,使用的并不是你提前mock好的对象
  • PowerMockito默认未开启native方法mock能力,需要通过注解声明需要处理的类来启用相关功能

修复步骤

第一步:引入正确的PowerMock依赖(未配置依赖时需要补全)

Maven配置示例如下,版本需和项目中JUnit、Mockito版本兼容,下述配置适配JUnit 4.12+、Mockito 2.x版本:

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>

第二步:修改测试类代码

增加必要注解、构造方法拦截逻辑,完整测试代码如下:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.junit.Assert.assertTrue;

@RunWith(PowerMockRunner.class)
@PrepareForTest({A.class, Util.class})
public class ATest {
    @Test
    public void test1() throws Exception {
        // 1.  mock A类实例,打桩native方法返回值
        A mockA = PowerMockito.mock(A.class);
        PowerMockito.when(mockA.test()).thenReturn("test");
        
        // 2. 拦截所有无参构造A的操作,返回我们提前mock好的实例
        PowerMockito.whenNew(A.class).withNoArguments().thenReturn(mockA);
        
        // 3. 执行测试逻辑并断言
        boolean check = Util.test().equals("test");
        assertTrue(check);
    }
}

关键说明

  • @RunWith(PowerMockRunner.class):指定使用PowerMock运行器执行测试,才能支持字节码修改、构造方法拦截等特殊能力
  • @PrepareForTest:声明需要PowerMock修改字节码的类,其中A.class用来启用native方法mock能力,Util.class用来支持拦截它内部的new A()操作
  • PowerMockito.whenNew:拦截A类的构造方法,保证Util内部创建的A实例就是我们提前mock好的对象,确保打桩逻辑生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:39:01