2016-04-27 62 views
0

我想測試IOExceptionIllegalArgumentException方法引發的properties.load(in)。根據這裏的文檔OracleDoc它說加載方法拋出IOException - 如果從輸入流中讀取時發生錯誤。 IllegalArgumentException - 如果輸入流包含格式錯誤的Unicode轉義序列。如何模擬Inputstream來加載Java中的屬性

這裏是我的代碼:

public class PropertiesRetriever { 

private String foo; 
private String foo1; 
private Properties properties; 

/** 
* Injects the properties file Path in the {GuiceModule} 
* Calls {@link PropertiesRetriever#loadPropertiesPath(String) to load the 
* properties file. 
*/ 

@Inject 
public PropertiesRetriever(@Named("propertiesPath") String propertiesPath,  Properties properties) 
    throws IOException { 
this.properties = properties; 
loadPropertiesPath(propertiesPath); 
} 

/** 
* Loads the properties file as inputstream. 
* 
*/ 
public void loadPropertiesPath(String path) throws IOException { 
InputStream in = this.getClass().getResourceAsStream(path); 
properties.load(in); 

} 

這裏,方法:

properties.load(in) 

拋出IOExceptionIllegalArgumentException。我想在JUnit測試中測試這個方法。無論如何,我可以稱之爲這些方法。

+0

[嘲諷的Java的InputStream(http://stackoverflow.com/questions/6371379/mocking-java-inputstream) –

回答

1

你有兩種選擇。要麼提供一些測試文件,這將創建預期的錯誤,或將Stream的模擬傳遞給屬性檢索器作爲參數。因此,而不是propertiesPath參數,您將直接inputStream(這種方法可能會將問題移到其他地方)。通過重構你的一些代碼Mocking Java InputStream

+0

的可能重複我走過的InputStream,但仍的模擬它不拋出IOException。有什麼方法可以測試這個嗎? – Jasmine

+0

如果我使用ArgumentCaptor來捕獲Inputstream.class並使用doThrow(IOException.class).when(mockProperties).load(reqCaptor.capture()),這會是一個好主意嗎?最後調用githubpropertiesRetreiver.loadPropertiesPath(filePath);並檢查IOException? – Jasmine

1

你可以這樣做:

如果你決定通過物流作爲一個參數,也有一些技巧,如何嘲笑它。這與使用或的Mockito其他一些嘲諷框架來創建一個行爲,你的願望一個InputStream(引發異常):

public void loadPropertiesPath(String path) throws IOException { 
    // Always close streams you open! 
    try (InputStream in = getIStream(path)) { 
     properties.load(in); 
    } 
} 

private InputStream getIStream(String path) { 
    InputStream in = this.getClass().getResourceAsStream(path); 

    return in; 
} 

您可以使用到的Mockito您的對象create a partial mock;模擬getIStream(String)返回模擬InputStream。當InputStream::read(byte[])被調用時,設置模擬來拋出你想要的異常。

如果您不想使用PowerMock,那麼您可以將getIStream(String)的可見性更改爲default。那麼普通的Mockito將做的工作:

@Test 
public void exceptionTest() throws IOException { 
    PropertiesRetriever pr = new PropertiesRetriever(); 
    PropertiesRetriever prSpy = spy(pr); 

    InputStream isMock = mock(InputStream.class); 
    doReturn(isMock).when(prSpy).getIStream(anyString()); 

    doThrow(new IllegalArgumentException("CRASH!")).when(isMock).read(any()); 

    prSpy.loadPropertiesPath("blah"); 
} 
+0

我實際上試圖避免使用PowerMock或Matchers.any()我打算只使用Mockito。 – Jasmine

+0

它仍然不拋出IOException或IllegalArgumentException。無論如何,我可以創建一個損壞的InputStream?還是我在這裏錯過了什麼? – Jasmine

+0

@Jasmine,你可以在'doThrow()'中指定所需的異常。在我的例子中,我使用了'IllegalArgumentException',但是你也可以拋出'IOException'及其子類或任何'RuntimeException'。 – Ralf