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

使用PowerMock的whenNew遇问题:JUnit测试B类Calculate方法问询

搞定PowerMock whenNew不生效的问题

看来你是想通过PowerMock的whenNew来控制B类的实例,进而测试Calculate方法对吧?先说说你当前代码的问题:你直接new B()创建实例,这会绕过PowerMock的mock拦截,所以whenNew根本不会生效。咱们一步步来调整:

1. 先修正@PrepareForTest注解

PowerMock要拦截new操作,得修改发起new操作的那个类的字节码——也就是你的test类。所以得把它加到@PrepareForTest里,而不是留空。

2. 用whenNew拦截B实例的创建

通过PowerMockito.whenNew()来指定,当代码里执行new B()时,返回你预先准备好的mock实例。这样后续调用b.Calculate()就会走mock的逻辑啦。

3. 完整的可运行示例

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 org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.ContextConfiguration;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application-context.xml")
// 重点:把创建B实例的test类加入PrepareForTest
@PrepareForTest(test.class)
public class test {

    @Test
    public void testCalculateWithMock() throws Exception {
        // 1. 创建B的mock对象
        B mockB = mock(B.class);
        
        // 2. 拦截new B()的调用,返回咱们的mock实例
        PowerMockito.whenNew(B.class).withNoArguments().thenReturn(mockB);
        
        // 3. 设定mock的Calculate方法返回值(比如故意返回false来测试断言)
        when(mockB.Calculate("Test", "Test")).thenReturn(false);
        
        // 4. 现在new B()得到的其实是mockB
        B b = new B();
        
        // 5. 调用方法并验证结果
        boolean result = b.Calculate("Test", "Test");
        assertFalse(result);
        
        // 6. 还能验证方法是否被正确调用了一次
        verify(mockB, times(1)).Calculate("Test", "Test");
    }
}

class B {
    public boolean Calculate(String x, String y){
        return true;
    }
}

几个关键提醒

  • @PrepareForTest的目标:一定要是执行new B()的类(这里是test),不是B类本身——PowerMock是通过修改发起创建操作的类的字节码来拦截new的。
  • 异常处理:whenNew会抛出Exception,所以测试方法要么声明throws Exception,要么捕获它。
  • 小建议:Java方法名建议用小驼峰,把Calculate改成calculate更符合编码规范哦~

另外,如果你的需求是测试B类Calculate方法的真实逻辑,那其实完全不需要用whenNew,直接创建实例调用就行,像你最初的代码那样,补充断言就好:

@Test
public void testCalculateRealLogic() {
    B b = new B();
    boolean result = b.Calculate("Test", "Test");
    // 验证真实方法的返回值是否符合预期
    assertTrue(result);
}

这样就能根据你的测试场景选对方法啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:42:24