我想知道是否有一种方法可以验证并调用为从测试中的公共静态方法调用的私有静态方法创建的模拟程序。
这是我正在测试的公共静态方法
public static String methodUnderTest(String p1){
return privateStaticMethod(p1);
}
private static String privateStaticMethod(String p1){
return "dummy";
}
我使用powermokito模拟了如下的私有静态方法:
@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "ClassUnderTest")
public class ClassUnderTestTest {
@Test
public void test_sometest() throws Exception {
PowerMockito.spy(ClassUnderTest.class);
PowerMockito.doReturn("whatever").when(ClassUnderTest.class, "privateStaticMethod","something");
String retValue = ClassUnderTest.methodUnderTest("something");
assertEquals(retValue, "whatever");
}
}
现在,有没有一种方法可以验证是否调用了privateStaticMethod?
答案 0 :(得分:1)
事实证明确实很复杂。
如果可以解决问题,则解决方案可能会遵循here所写内容。不幸的是,我没有PowerMockito设置,所以我自己无法测试此代码:
asyncfunction
上面的代码使用Hamcrest // tell powermock(ito) that you want to do PARTIAL static mocking
PowerMockito.spy(ClassUnderTest.class);
// give it the mocking SPEC for that static method that needs mocking
PowerMockito.doReturn("whatever").when(ClassUnderTest.class, "privateStaticMethod","something");
// tell it to INVOKE the real method when the public one is called
PowerMockito.doCallRealMethod().when(Util, "methodUnderTest", any());
// now assert that the mock spec kicked in
assertThat(ClassUnderTest.methodUnderTest("something"), is("whatever"));
匹配器,而is()
将是(Power)Mockito参数匹配器。确保导入正确!
当您更改公用方法并且不调用该私有方法和/或返回其他内容时,以上操作将失败。
但真正的答案是:您应该避免这种测试。上面的代码隐式验证此私有方法已被调用:如果未调用该私有方法,您将收到不同的结果!
但是这里的重点是:您不应该测试这种东西。 如何公开方法如何获得结果与您的测试完全无关。您的公共方法有一个合同,如何实现它是实现 detail 。
您的方法将单元测试变成生产代码的(过于复杂!)重新实现。这意味着:您打算更改实施的第二次测试就需要调整。更糟糕的是,因为您将方法名称作为原始字符串传递,所以您甚至不会注意到,直到运行时,该方法突然停止返回any()
,而给您whatever
。
所以,这里的 real 答案是:
毫无意义以验证是否调用了私有方法。您的公共方法的调用者应该返回“什么进来,什么回来”的信息。在该级别上,其他任何内容都无关紧要。
给出OP的评论:
换句话说:如果您不能在Mockito中编写简单的直接测试,那么最有可能您创建了难以测试的生产代码,那么花时间和精力来做会更好。使生产代码更易于测试的精力。不必使用PowerMock(ito)锤通过解决症状来“解决”您的问题。是的,这很重要。我们来自基于PowerMock的“太多静态”代码库,只是在某个时候告诉人们“不再”。从那时起,当我们需要模拟时,我们使用Mockito。由于在不同地方“更改为静态”而导致的离奇的“单元测试失败”的数量减少到了0。我们的生产代码变得更好了。