2017-03-20 82 views
0

我試圖嘲弄在單元測試情況如下功能:嘲諷Files.copy春季啓動單元測試

Files.copy(response.getBody(), pathObj, StandardCopyOption.REPLACE_EXISTING); 

StandardCopyOptionjava.nio.file包的枚舉:

的方式我想嘲笑是:

try { 
     Mockito.doNothing().when(Files.copy(Mockito.any(InputStream.class), Mockito.any(Path.class), Mockito.any(CopyOption.class))); 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 

但我收到以下錯誤:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers! 
0 matchers expected, 3 recorded: 
-> at scheduler.DownloadTest.downloadFile(DownloadTest.java:227) 
-> at scheduler.DownloadTest.downloadFile(DownloadTest.java:227) 
-> at scheduler.DownloadTest.downloadFile(DownloadTest.java:227) 

This exception may occur if matchers are combined with raw values: 
    //incorrect: 
    someMethod(anyObject(), "raw String"); 
When using matchers, all arguments have to be provided by matchers. 
For example: 
    //correct: 
    someMethod(anyObject(), eq("String by matcher")); 
+0

您可以使用內存中的文件系統嗎? https://github.com/google/jimfs –

+0

mdewit完全正確;你不能使用Mockito來模擬靜態方法(也許你想花一些時間閱讀Mockito文檔;這樣的事情在那裏有明確的說明)。所以,唯一的兩個選擇是:讓你的不可測試的設計可測試;通過遵循這個答案;或轉向PowerMock(ito)。我強烈建議去第一個選項。 – GhostCat

回答

1

問題是你試圖模擬一個靜態方法。 Mockito不允許這樣做。您只能爲實際模擬類實例的非靜態方法提供行爲。

當您使用

Mockito.doNothing().when(Files.copy(Mockito.any(InputStream.class), Mockito.any(Path.class), Mockito.any(CopyOption.class))); 

在()方法時,預計的Mockito引用您試圖嘲笑類。然後,您需要使用其參數指定方法。

如:

Mockito.doNothing().when(classInstance).copy(...) 

然而,由於副本在這種情況下是一個靜態方法,上面是不行的(在你的代碼提供Files.copy的返回值作爲類的引用)。因此,一種解決方案是使用PowerMock(它可以嘲諷靜態方法,但與mockito的更高版本不兼容),或者將文件類包裝在實例包裝中。

如:

class FilesWrapper { 
    public long copy(InputStream in, Path target, CopyOption... options) { 
     return Files.copy(in, target, options); 
    } 
} 

現在,注入嘲笑FilesWrapper實例(Mockito.mock(FilesWrapper.class))到你的代碼,並隨時隨地使用Files.copy使用它。由於mockito的默認行爲是對模擬類實例的方法不做任何事情,所以您只需創建模擬。

另一種替代方法是將Files.copy部分移動到被測試類的受保護方法中。這個受保護的方法可以在測試過程中被覆蓋。