2016-12-23 37 views
1

我一直在努力理解由jmockit Mocking API支持的類雷區。我發現我認爲是File的一個bug,但是這個問題只是簡單的說了「不要模擬文件或路徑」,這是沒有任何解釋的。有人能在這裏幫助我理解爲什麼某些類不應該被嘲笑,以及我應該如何解決這個問題。我正在嘗試通過bug報告向圖書館作出貢獻,但是我提交的每一份報告都讓我更加困惑。請原諒我的無知,但是如果有人能指出我禁止嘲笑的理由,我會非常感激。爲什麼我不應該嘲笑文件或路徑

回答

3

我不確定有一個傻瓜證明的規則列表。這些事情總是有一定的知識和品味。教條通常不是一個好主意。

我投票結束這個問題,因爲我認爲很多是意見。

但是就這樣說,我會做一個嘗試。

單元測試應該是測試單個類,而不是類之間的交互。這些被稱爲集成測試。

如果你的對象調用其他遠程對象,如服務,你應該嘲笑那些返回測試所需的數據。這個想法是服務和他們的客戶也應該在他們自己的單元測試中單獨測試。測試一個依賴於它們的類時,不需要重複這些。

在我看來,這個規則的一個例外是數據訪問對象。在沒有連接到遠程數據庫的情況下測試其中之一是沒有意義的。您的測試需要證明代碼的正確運行。對於數據訪問對象,這需要數據庫連接。這些應該寫成事務性的:對數據庫進行種子處理,執行測試,並將測試的操作反轉。完成後數據庫應該處於相同狀態。

一旦您的數據訪問對象被認證爲正常工作,所有使用它們的客戶端都應該嘲笑它們。無需重新測試。

你不應該在JVM中模擬類。

你問爲什麼關於文件或流尤其是 - 這是一個。採取或忽略它。

您不必測試JVM類,因爲Sun/Oracle已經這樣做了。你知道他們工作。你希望你的班級使用這些班級,因爲一個失敗的考試將暴露必要的文件不可用的事實。模擬不會告訴我,我忽略了將必需的文件放入我的CLASSPATH中。我想在測試過程中發現,而不是在生產中。

另一個原因是單元測試也是文檔。這是一個爲他人展示如何正確使用你的課程的現場演示。

+0

我還是不明白爲什麼我不應該能夠模擬一個File對象。我應該只注入字符串和流,直接從文件或路徑?當然,我也必須說服我的團隊中的所有其他開發人員。 – Novaterata

+0

嘲笑文件究竟意味着什麼?你爲什麼如此堅決?如果你的團隊中的每個人都告訴你這不是一個好主意,那麼你爲什麼如此着迷?我已經給了你一個有意義的例子 - 服務 - 這不是一個字符串或流。通過一切手段這樣做。如果它適合你,那麼很好。如果沒有,承認這是浪費時間,繼續前進。 – duffymo

+0

我想你誤會,我會是一個說服我的團隊的其他成員不嘲笑文件。我非常關注它,因爲我的團隊的其他成員將一個文件注入了一個類。這意味着getAbsolutePath的調用需要被模擬。 – Novaterata

2

在單元測試中,您必須測試您的代碼是否正確。您可以剔除任何不是正在測試的直接代碼的外部代碼段。這是對單元測試的嚴格定義,它假設有另一種形式的測試稱爲集成測試,稍後將進行。在集成測試中,您可以測試代碼如何與外部元素(如數據庫或其他Web服務,網絡或硬盤驅動器)交互。

如果我有一段與對象交互的代碼(例如文件),並且我的代碼對該文件做了3件事,那麼在我的單元測試中,我將測試我的代碼完成了這三件事情。

例如:

public void processFile(File f) { 
    if (f.exists()) { 
     //perform some tasks 
    } else { 
     //perform some other tasks 
    } 
} 

爲了正確單元測試上面的代碼我將運行的至少兩個單元測試。一個用於測試文件是否存在,另一個用於測試我的代碼在文件不存在時執行正確的操作。由於單元測試,恕我直言,只是測試我的代碼,而不是做集成測試,那麼它是完美的罰款,以模擬文件,以便您可以測試這種方法的兩個分支。

在集成測試,那麼你可以用一個真實的文件,測試您的應用程序將與周圍的環境進行交互。

嘗試的Mockito:

我不知道爲什麼jmockit不允許嘲笑File類。在Mockito中可以完成。下面的例子。

import java.io.File; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

public class NewMain {  

    public static void main(String[] args) { 
     File f = mock(File.class); 
     when(f.exists()).thenReturn(true); 
     System.out.println("f.exists = " + f.exists()); 
    } 

} 
+0

這就是我的想法,但它不再支持jmockit。或者至少不認爲值得修正錯誤。 – Novaterata

+0

添加了如何使用Mockito來模擬它的代碼。 –

相關問題