我有一个类,我想用一个调用另一个类的私有方法的公共方法来测试。当我尝试调用同一个类的私有方法时,一切都很完美。当我尝试模拟从被测试的类调用的另一个私有方法时,问题就出现了。以下是测试类的代码示例。
@RunWith(PowerMockRunner.class)
@PrepareForTest({CodeWithPrivateMethod.class,CodeWithAnotherPrivateMethod.class})
public class CodeWithPrivateMethodTest {
@Test
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
CodeWithAnotherPrivateMethod codeWithAnotherPrivateMethod = PowerMockito.spy(new CodeWithAnotherPrivateMethod());
/*when(codeWithAnotherPrivateMethod, method(CodeWithAnotherPrivateMethod.class, "doTheGame", String.class))
.withArguments(anyString())
.thenReturn(true);*/
PowerMockito.when(codeWithAnotherPrivateMethod, "doTheGame", anyString()).thenReturn(true);
//PowerMockito.doReturn(true).when(codeWithAnotherPrivateMethod, "doTheGamble", anyString(),anyInt());
spy.meaningfulPublicApi();
}
}
以下是被测试类的代码示例
import java.util.Random;
public class CodeWithPrivateMethod {
CodeWithAnotherPrivateMethod anotherPrivateMethod = new CodeWithAnotherPrivateMethod();
public void meaningfulPublicApi() {
if (anotherPrivateMethod.doTheGame("Whatever")) {
System.out.println("kaboom");
}
}
}
以下是从测试类中调用的类的代码示例
import java.util.Random;
public class CodeWithAnotherPrivateMethod {
public boolean doTheGame(String string) {
return doTheGamble("Whatever", 1 << 3);
}
private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}
所以我的问题是我如何成功地模拟CodeWithAnotherPrivateMethod类的doTheGamble()方法以使其始终返回true?
答案 0 :(得分:2)
此处的问题是,虽然您在测试中创建了CodeWithAnotherPrivateMethod
的间谍,但在CodeWithAnotherPrivateMethod
中创建了CodeWithPrivateMethod
的新实例。所以,实际上你并没有使用你的模拟。
CodeWithAnotherPrivateMethod anotherPrivateMethod = new CodeWithAnotherPrivateMethod();
为避免这种情况,您可以强制在创建新实例时返回CodeWithAnotherPrivateMethod模拟。您可以使用PowerMockito whenNew()
功能执行此操作。
示例:
PowerMockito.whenNew(CodeWithAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithAnotherPrivateMethod);
最后,您的测试应该是这样的:
@Test
public void when_gambling_is_true_then_always_explode() throws Exception {
// Spy CodeWithAnotherPrivateMethod and force return true when doTheGamble is called
CodeWithAnotherPrivateMethod codeWithAnotherPrivateMethod = PowerMockito.spy(new CodeWithAnotherPrivateMethod());
PowerMockito.doReturn(true).when(codeWithAnotherPrivateMethod, "doTheGamble", Mockito.anyString(), Mockito.anyInt());
// Return your mock when a new instance of CodeWithAnotherPrivateMethod is created.
PowerMockito.whenNew(CodeWithAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithAnotherPrivateMethod);
CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
spy.meaningfulPublicApi();
}
希望它有所帮助。