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

为何配置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 18:45:09