簡體   English   中英

私人方法的Junit測試

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM