如何模拟使用PowerMock进行testing的私有方法?

我有一个课程,我想用一个公开的方法来testing私人课程。 我想假设私人方法正常工作。 举个例子,我doReturn....when... 我发现有可能使用PowerMock的解决scheme ,但这种解决scheme不适合我。 它是如何完成的? 有没有人有这个问题?

我在这里没有看到问题。 通过使用Mockito API的以下代码,我设法做到了这一点:

 public class CodeWithPrivateMethod { public void meaningfulPublicApi() { if (doTheGamble("Whatever", 1 << 3)) { throw new RuntimeException("boom"); } } private boolean doTheGamble(String whatever, int binary) { Random random = new Random(System.nanoTime()); boolean gamble = random.nextBoolean(); return gamble; } } 

这里是JUnittesting:

 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.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.powermock.api.mockito.PowerMockito.when; import static org.powermock.api.support.membermodification.MemberMatcher.method; @RunWith(PowerMockRunner.class) @PrepareForTest(CodeWithPrivateMethod.class) public class CodeWithPrivateMethodTest { @Test(expected = RuntimeException.class) public void when_gambling_is_true_then_always_explode() throws Exception { CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod()); when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class)) .withArguments(anyString(), anyInt()) .thenReturn(true); spy.meaningfulPublicApi(); } } 

一个能够与任何testing框架一起工作的通用解决scheme( 如果你的类不是final )是手动创build你自己的模拟。

  1. 改变你的私人方法保护。
  2. 在你的testing类中扩展类
  3. 重写之前的私有方法来返回任何你想要的常量

这不使用任何框架,所以它不优雅,但它将始终工作:即使没有PowerMock。 或者,如果您已经完成了第一步,您可以使用Mockito为您执行步骤#2和#3。

要直接模拟私有方法,您需要使用PowerMock,如其他答案中所示。

我知道你可以叫你私人函数在mockito中testing的方式

 @Test public void commandEndHandlerTest() throws Exception { Method retryClientDetail_privateMethod =yourclass.class.getDeclaredMethod("Your_function_name",null); retryClientDetail_privateMethod.setAccessible(true); retryClientDetail_privateMethod.invoke(yourclass.class, null); }