为何配置PowerMock的whenNew后仍不返回预期Mock对象?
PowerMock
whenNew 不生效的常见问题排查 核心问题点
- 测试方法缺少JUnit的
@Test注解
你当前编写的testFoo方法未添加@Test注解,JUnit框架不会识别并执行该方法,你看到的(2,3)输出大概率是其他运行路径触发的MyClass调用,根本未走到mock逻辑。 - 未声明
whenNew方法的受检异常PowerMockito.whenNew签名自带受检异常声明,若测试方法未添加throws Exception,会导致代码编译不通过,实际运行的是未包含mock逻辑的旧版本class文件。 - 测试框架不适配
若你使用的是JUnit5框架,@RunWith(PowerMockRunner.class)是JUnit4专用注解,需替换为JUnit5适配的PowerMock扩展,否则PowerMock的字节码织入逻辑完全不会启动。 - 依赖版本不匹配
Gradle项目中若PowerMock版本、JUnit版本、Mockito版本、字节码操作依赖(ByteBuddy/Objenesis)版本未做适配,会导致@PrepareForTest的字节码织入失效,代理逻辑无法插入到new对象的执行流程中。 - 类加载路径异常
若MyClass或Point类被提前加载到PowerMock无法修改的类加载器(比如作为系统依赖、预加载的jar包),会导致字节码修改失败,whenNew无法拦截构造调用。
修正后的测试类示例
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 java.awt.Point; @RunWith(PowerMockRunner.class) // 织入目标为执行new操作的MyClass,若mock的是JDK内置类需将其也加入数组 @PrepareForTest({MyClass.class, Point.class}) public class MyClassTest { @Test // 必须添加@Test注解让JUnit识别测试方法 public void testFoo() throws Exception { // 声明异常兼容whenNew的受检异常 MyClass c = new MyClass(); // 使用mock对象验证拦截效果,避免真实对象干扰判断 Point mockPoint = PowerMockito.mock(Point.class); PowerMockito.whenNew(Point.class).withAnyArguments().thenReturn(mockPoint); c.foo(); // 可添加验证逻辑确认构造器被拦截 PowerMockito.verifyNew(Point.class).withArguments(2, 3); } }
注意:如果你的Point是自定义类而非JDK内置的
java.awt.Point,无需将其加入@PrepareForTest数组,只需保留执行new操作的MyClass即可。
内容的提问来源于stack exchange,提问作者James Chen
相关产品推荐
相关产品推荐

