使用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
相关产品推荐
相关产品推荐

