2017-03-22 94 views
1

我試圖覆蓋處理文件的代碼。我試圖避免使用真實文件進行測試,所以我使用Mockito。 這是我想測試代碼:Junit - 模擬一個文件

try { 
    byte[] data = Files.readAllBytes(((File) body).toPath()); 
    immutableBody = data; 
    actualHeaderParams.put(HttpHeaders.CONTENT_LENGTH, (new Integer(data.length)).toString()); 
    contentType = MediaType.APPLICATION_OCTET_STREAM; 
    } 

我使用的是模擬文件:

File mockedFile = Mockito.mock(File.class); 

,但我得到「toPath」異常。所以我添加了一些路徑或null,但是然後我再次得到Exceptions,因爲文件不存在於路徑中。

when(mockedFile.toPath()).thenReturn(Paths.get("test.txt")); 

越來越:

com.http.ApiException: There was a problem reading the file: test.txt 

有沒有辦法做,而無需創建用於測試一個真正的文件?

+0

找到一種方法來傳遞內容,並且將您碰巧從文件中讀取的事實外化。更改方法簽名以移出字節源。 – duffymo

+0

它通常更容易使用'@Rule public TemporaryFolder folder = new TemporaryFolder()'並且創建你需要的「假」文件內容。嘲笑文件可能會非常快速地變得痛苦。 – cjstehno

回答

0

我不知道有一種簡單的方法,但我可能是錯的。您可能需要模擬靜態Files.readAllBytes()方法,您需要使用PowerMock之類的方法。或者你可以在一個方法把這個包然後你可以嘲笑的行爲:

public byte[] getAllBytesWrapper(File body) { 
    return Files.readAllBytes(body.toPath()); 
} 

,然後有這個方法的模擬:

when(classUnderTest.getAllBytesWrapper(any(File.class))).thenReturn("test".getBytes()); 
5

既然你要嘲笑文件的閱讀中,我承擔你在這個班,你想在隔離測試一些邏輯(不使用實際的文件),因此我建議:

移動閱讀文件到一個單獨的類的責任,這樣反而有:

byte[] data = Files.readAllBytes(((File) body).toPath()); 

交錯與您的業務邏輯,具有:

byte[] data = fileReader.read(body); 

fileReader將是你的類的實例與沿着這些路線非常簡單的實現:

class FileToBytesReader { 
    byte[] read(File file) throws IOException { 
    return Files.readAllBytes(((File) body).toPath()); 
    } 
} 

然後在您的測試,你可以用模擬替代fileReader,你可以設定期望值。

如果您使用的是Java 8你沒有創建FileToBytesReader類,但你可以使用java.util.Function

Function<File, byte[]> fileReader = (file) -> { 
    try { 
    return Files.readAllBytes(((File) file).toPath()); 
    } catch (IOException e) { 
    throw new UncheckedIOException(e); 
    } 
}; 

BTW。如果您正在使用遺留代碼並且無法更改生產代碼,那麼您必須使用PowerMock來模擬此靜態方法。

0

以Matchers.any()爲參數模擬Files.readAllBytes()。並返回一個字節數組。