一般情況下私有方法只能在所屬類的內部進行調用,在類外則無法通過對象.方法名的方法調用私有方法。在Junit中對私有方法進行測試有兩種方法:
方法一:使用PowerMock測試私有方法:
Object result = Deencapsulation.invoke(mockClass, methodName, parameter1, parameter2....)
其中:
1.mockClass:該參數是需要被調用方法所屬的類,該類需要被mock
2.methodName:該參數是需要被調用的私有方法的名稱
3.parameter:該參數為調用方法的參數的值
4.Deencapsulation.invoke():返回結果類型,與調用方法(即測試方法)的返回類型一致
方法二:通過反射機制測試私有方法:
Method method = 類對象.getclass().getDeclaredMethod(methodName, 參數類型1, 參數類型2....)
Object result = method.invoke(類對象, 參數值1, 參數值2....)
其中:
1類對象:調用私有方法所屬類的對象
2.methodName:調用的私有方法名
3.method.setAccessible(true)指定私有方法可測試權限
常用反射法測試:
eg1:
@Test
public void add2()
{
Calculator c=new Calculator();
Class<Calculator> cal=Calculator.class;
try {
Method method=cal.getDeclaredMethod("add2", new Class[]{int.class,int.class});
method.setAccessible(true);
Object obj=method.invoke(c, new Object[]{1,2});
Assert.assertEquals(3, obj);
} catch (Exception e) {
Assert.fail("-----");
}
}
eg2:
/**
* 測試私有權限方法前,修改方法權限
*
* @param target 目標對象
* @param functionName 字段的名稱
* @param parameters 值
*/
public static Object setAccess4PrivateFunction(Object target, String functionName, Object[] parameters) throws
NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<?> clazz = target.getClass();
if (parameters == null || parameters.length == 0) {
Method method = clazz.getDeclaredMethod(functionName);
method.setAccessible(true);
return method.invoke(target);
}
int count = parameters.length;
Class<?>[] paraClass = new Class[count];
int index = 0;
for (Object para : parameters) {
Class<?> tmpClass = para.getClass();
if (tmpClass.equals(LinkedHashMap.class) || tmpClass.equals(HashMap.class)) {
paraClass[index] = Map.class;
} else {
paraClass[index] = tmpClass;
}
index++;
}
Method method = clazz.getDeclaredMethod(functionName, paraClass);
method.setAccessible(true);
return method.invoke(target, parameters);
}