[英]java unit test of a method interacting with binary files in filesystem
我是Java編程的新手,但我將嘗試使用正確的術語並盡可能避免誤解。
我已經找到了一些與我的問題非常相似的主題的答案,但是或者我只是看不到它們如何真正適合我的問題,或者也許它們真的不適合我。 其中一些使用模擬對象,但是我不確定這是否是正確的選擇。
我需要有一個對象數組,該對象的信息是從隨機訪問的二進制文件中加載的。 二進制文件的第一個字節是文件的頭,它定義了數據在文件中的存儲方式,基本上說了一些字段的長度,這些字段有助於計算所需數據在文件中的位置。
因此,現在我想測試將由UnitListElement對象指定的所需數據加載到Unit對象的調用方法。 為此,我只關注二進制文件的單次讀取。
我有一個名為Unit的Java類,具有一些屬性,比如a ,* b *和c 。 此屬性的值通過方法調用getDataFromBinFile加載:
public class Unit{
public double[] a;
public double[] b;
public double[] c;
getDataFromBinFile(UnitListElement element){
<here loads the data from the binary file with random access>
}
}
從二進制文件加載數據的方法,打開二進制文件並訪問二進制文件中的所需數據。 要讀取的所需數據在UnitListElement對象中指定:
public class UnitListElement{
public String pathOfFile;
public int beginToReadAt; // info related to where the desired data begins
public int finishReading; // info related to where the desired data ends
}
屬性beginToReadAt和finishReading時間參考與二進制文件的標頭一起用於計算要從二進制文件讀取的第一個和最后一個字節位置。
因此,我需要做的是一個測試,在該測試中調用方法getDataFromBinFile(unitListEl)並測試返回的信息是否正確。
第一種選擇
在一些存在類似問題的帖子中,建議使用模擬對象。 我試圖找到有關模擬對象的文檔,但沒有找到任何簡單的初學者指南。 因此,盡管我不太了解模擬對象,但我的印象是,這種情況不適合這種情況,因為我要測試的是二進制文件的讀取,而不僅僅是與其他對象的交互。
第二選擇
另一種選擇是使用幫助器方法在測試內部創建測試的二進制文件,使用@BeforeClass創建fi,然后使用該臨時文件運行測試,然后使用@AfterClass方法將其刪除。
您認為考慮TDD方法的最佳實踐是什么? 模擬對象真的適合這種情況嗎? 如果有的話,是否有針對初學者的文檔以及基本示例?
還是另一方面,文件的創建更適合測試閱讀方法?
提前非常感謝。
可以將模擬應用於您的案例,但實際上在這里並非絕對必要。 您所需要做的就是將getDataFromBinFile
的實際數據處理邏輯與從文件中讀取字節的代碼分離。
您可以(至少)通過兩種方式實現此目的:
UnitListElement
並返回字節數組的接口方法后面,然后在getDataFromBinFile
使用它。 然后,您可以使用模擬讀取器在測試中模擬此接口,該讀取器僅返回一些預定義的字節,而無需訪問任何文件。 (或者,您可以將文件讀取邏輯移到UnitListElement
本身中,因為現在看來它是一個POD類。) getDataFromBinFile
的簽名以采用字節數組參數代替UnitListElement
。 在實際的生產代碼中,您可以從UnitListElement
描述的文件位置讀取數據,然后將其傳遞給getDataFromBinFile
。 在單元測試中,您可以直接將任何二進制數據傳遞給它。 (請注意,在這種情況下,將您的方法重命名為getDataFromBytes
類的方法很有意義。) 對於模擬,到目前為止,我一直在使用EasyMock。 我發現其文檔相當容易理解,希望能對您有所幫助。
我在TDD中沒有太多經驗。 測試文件讀寫時,不需要使用模擬,最好的選擇是擁有要在其上運行測試文件的測試版本。 當您無法輕松為用例創建可測試對象時,即例如在測試與服務器的交互時,應使用模擬。
我不喜歡創建測試二進制文件,因為要讀取的文件格式的任何變化都意味着也要更改測試文件(從而改變測試)。
由於您遵循的是TDD方法,因此必須為“ UnitListElement”類編寫測試,因此對於這種情況,模擬似乎是一個更好的解決方案。 您的目標是測試“ getDataFromBinFile”方法而不是“ UnitListElement”類方法(當前),因此您可以模擬“ UnitListElement”類(或由它繼承並傳遞給getDataFromBinFile方法的接口)。 模擬“ UnitListElement”意味着,只要在“ getDataFromBinFile”方法中對其進行訪問,就可以向該類中的任何方法調用返回預定義或任何特定的返回值。 最后,您可以在“ getDataFromBinFile”方法中使用模擬返回的值,並在執行業務邏輯后聲明該方法的返回值。 我沒有使用太多的模擬框架,但是大多數情況下我一直在使用EasyMock框架。首先,您可以在此處獲得EasyMock的基本示例
只需制作一個測試二進制文件。
此過程正在讀取文件。 因此,沒有理由擔心文件系統。 該文件將始終是確定性的(如果您在閱讀時更改了文件,那將是另一回事)
如果您想在讀完對象后對它們進行測試,我建議您僅在測試中創建它們(除非很難做到,就像聲音文件一樣)
另外,我建議使用流而不是文件的抽象,但是我仍將使用測試文件進行測試。 順便說一句:確保測試文件很小,畢竟是測試。
有人可能會辯稱“不是應該測試文件系統”,但是您認為.class文件從哪里加載?
另外,我將通過java classLoader獲取流
this.getClass().getResourceAsStream("yourfile.name");
測試愉快!
勒韋林·法爾科
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.