当我使用Powermock模拟私有方法,然后在另一个方法的单元测试中验证它时,检查它是否被调用并且时间正确。但是我发现我可以验证方法是否被调用并且使用正确的参数,方法的被调用时间可以是任何数字,但是单元测试总是通过。如果有人可以帮我解决问题。 THX!
这是我的源代码:
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());
...并重新运行测试用例。结果也通过了。但实际上我只在setUnitCount
中调用方法Refo
。
测试框架的版本:mockito:1.10.19; powermock:1.6.5
如何使用API PowerMockito.verifyPrivate()确认私有方法的通话时间;
答案 0 :(得分:1)
你做得对,除了一件事。你在监视枚举常数。每个枚举常量都是独立的内部类。所以你必须添加两件事:
@PrepareForTest
将枚举常量设置为fullyQualifiedNames
,例如`@PrepareForTest(values = {ConversionCommon.class,LengthConversion.class},fullyQualifiedNames =“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");
}
}
完整示例,您可能会找到here