[英]Junit Test of private mthods
我正在嘗試編寫一個實用工具方法,以便在被測試的類中輕松調用私有方法。 我有的是這個:
private Object callPrivateMethod(String methodName, Object subject, Object... parameters) {
try {
Class<?>[] paramTypes = new Class<?>[parameters.length];
for (int index=0; index<parameters.length; index++) {
paramTypes[index] = parameters[index].getClass();
}
Method method = subject.getClass().getDeclaredMethod(methodName, paramTypes);
method.setAccessible(true);
return method.invoke(subject, parameters);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
return null;
}
}
但是當我嘗試使用此代碼調用它時:
List<Session> sessions = new ArrayList<Session>();
// fill the array list
String sessionLines = (String) callPrivateMethod("getSessionsForEmail", emailSender, sessions);
我得到這個例外:
java.lang.NoSuchMethodException: staffing.server.email.EmailSender.getSessionsForEmail(java.util.ArrayList)
EmailSender(測試中的類)中的方法簽名如下所示:
private String getSessionsForEmail(List<Session> sessions) {
//do stuff
}
試圖弄清楚為什么反射找不到方法。 與List和ArrayList不完全相同的類是什么? 如果是這樣,我該怎么辦?
最好不要直接測試私有方法。 通過公共和/或受保護的方法訪問它們,我們正在測試系統在生產中的表現。 此方法還允許您通過公共/受保護方法發送所有數據組合來管理測試覆蓋率。
可以通過在測試源文件夾中具有相同的包名來測試受保護的方法。
如果測試私有方法是必須的,那么你可能會使用諸如Powermock之類的模擬工具,最好是使用Mockito,而不是自己進行反射。 這兩個工具都與JUnit有很好的集成。 這是一個陡峭的學習曲線,但值得投資。 這里有更多細節: 使用mockito測試私有方法
您的代碼嘗試查找將ArrayList
(具體的sessions
類)作為參數的方法。 但是您的方法不會將ArrayList
作為參數。 它以List
作為參數。
除了參數值之外,您還需要傳遞方法參數的類型。
或者您可以重構代碼並使方法受保護或受包保護,或者將其作為公共方法放在另一個協作類中。
目前的推理說你不應該測試私有方法。 它們是特定於實現的,應該通過調用它們的方法進行測試。 或者他們應該被提取到他們自己的班級並通過它進行測試。 我們的想法是,如果你有私人方法,他們需要單獨測試,你的課程做得太多,應該分手。
以這種方式看待它有很多好處,而不是最不能逃避你的課程來測試它。
如果你真的希望自己的實現成功,我覺得它可能有用: 在Java中輸入erasure 。
否則,正如Akber Choudhry指出的那樣,Mockito附帶了一個很好的實用程序包,名為org.powermock.reflect.Whitebox。 我肯定會用它。
最后,我不會說永遠不會測試私有方法,但如果你打算測試它們,請三思而后行。 保持基於反射的方法並不是最簡單的方法,而且非常容易出錯。
這可以通過JUnit4 + Mockito完成 。
要模擬私有方法,我們可以簡單地使用mockit.Deencapsulation包:
Deencapsulation.invoke(myService, "methodName", arg1, arg2);
我們可以根據要求用Mockito.anyString()等替換參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.