当我使用 Powermock 模拟私有方法,然后在另一个方法的单元测试中验证它时,检查它是否被调用并且时间正确。但是我发现我可以验证该方法是否被调用,并且使用正确的参数,该方法的调用次数可以是任何数字,但是单元测试总是通过。如果有人能帮我解决问题。感谢!
这是我的源代码:
public enum ConversionCommon{
INSTANCE;
...
public void getConvertTypeData(JSONObject result, JSONObject conversionData, String intent){
String uncertainty = "";
String unit1 = "";
String unit1_char = "";
if(result.has(ConversionDefine.CONVERSION_UNCERTAINTY)){
uncertainty = result.getString(ConversionDefine.CONVERSION_UNCERTAINTY);
}
if(result.has(ConversionDefine.CONVERSION_UNIT1)){
unit1 = result.getString(ConversionDefine.CONVERSION_UNIT1);
}
if(result.has(ConversionDefine.CONVERSION_UNIT1_CHAR)){
unit1_char = result.getString(ConversionDefine.CONVERSION_UNIT1_CHAR);
}
setUnitCount(conversionData, uncertainty, intent);
setDestUnits(conversionData, unit1, unit1_char);
}
}
方法getConvertTypeData()调用两个方法一次。以下是我的测试用例代码:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ ConversionCommon.class, LengthConversion.class })
@PowerMockIgnore("javax.management.*")
public class ConversionCommonTest{
@Before
public void setUp() throws Exception{
PowerMockito.mockStatic(LengthConversion.class);//
PowerMockito.spy(LengthConversion.class); //
}
@Test
public void should_getConvertTypeData_invoke_setUnitCount() throws Exception{
JSONObject result = new JSONObject();
JSONObject conversionData = new JSONObject();
result.put(ConversionDefine.CONVERSION_UNCERTAINTY, "3");
result.put(ConversionDefine.CONVERSION_UNIT1, "meter");
result.put(ConversionDefine.CONVERSION_UNIT1_CHAR, "centmeter");
suppress(method(ConversionCommon.class, "setUnitCount", JSONObject.class, String.class, String.class));
ConversionCommon.INSTANCE.getConvertTypeData(result, conversionData, ConversionDefine.INTENT_LENGTH_CONVERSION);
PowerMockito.verifyPrivate(ConversionCommon.INSTANCE, Mockito.times(1)).invoke("setUnitCount", Mockito.anyObject(), Mockito.anyString(), Mockito.anyString());
}
测试用例可以成功运行,但是如果我将最后一行更改为...
PowerMockito.verifyPrivate(ConversionCommon.INSTANCE, Mockito.times(100)).invoke("setUnitCount", Mockito.anyObject(), Mockito.anyString(), Mockito.anyString());
。并重新运行测试用例。结果也通过。但实际上我只在Refo
中调用该方法setUnitCount
一次。
测试框架版本:模拟:1.10.19;功率模拟:1.6.5
如何使用 API PowerMockito.verifyPrivate() 正确验证私有方法的调用时间;
你做对了,除了一件事。您正在监视枚举常量。每个枚举常量都是单独的内部类。因此,您必须添加两件事:
- 使用
fullyQualifiedNames
@PrepareForTest
的枚举常量,例如'@PrepareForTest(values = { ConversionCommon.class, LengthConversion.class }, fullQualifiedNames = "com.somepackage.ConversionCommon$INSTANCE") - 例如,创建间谍:
PowerMockito.spy(ConversionCommon.INSTANCE)
- 将常量替换为间谍:
Whitebox.setInternalState(ConversionCommon.class, spy)
- 现在,您可以像往常一样存根间谍方法
doNothing().when(spy, "setUnitCount");
通过枚举实现的一些抽象单例的代码片段:
枚举
public enum Singleton {
INSTANCE;
public void doSomething(){
callPrivateMethod();
}
private void callPrivateMethod() {
}
}
测试
RunWith(PowerMockRunner.class)
@PrepareForTest(value = Singleton.class, fullyQualifiedNames = "com.stackoverflow.q46212600.Singleton$INSTANCE")
public class ClassUseSingletonTest {
@Test
public void should_verify_enum_method() throws Exception {
final Singleton spy = PowerMockito.spy(Singleton.INSTANCE);
Whitebox.setInternalState(Singleton.class, spy);
doNothing().when(spy, "callPrivateMethod");
new ClassUseSingletone().doSomething("do");
PowerMockito.verifyPrivate(Singleton.INSTANCE, times(1)).invoke("callPrivateMethod");
}
}
完整示例,您可以在此处找到