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

