2016-04-27 11 views
0

Ich wollte die IOException und IllegalArgumentException geworfen von properties.load(in) Methode testen. Wie in der Dokumentation hier OracleDoc heißt es die Lade-Methode wirft IOException - wenn ein Fehler beim Lesen aus dem Eingabestream aufgetreten ist. IllegalArgumentException - Wenn der Eingabestream eine ungültige Unicode-Escape-Sequenz enthält.Wie man Inputstream vortäuscht, um Eigenschaften in Java zu laden

Hier ist mein Code:

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); 

} 

Hier wird ein Verfahren:

properties.load(in) 

wirft IOException und IllegalArgumentException. Ich wollte diese Methoden im JUnit Test testen. Kann ich diese Methoden trotzdem nennen?

+0

Mögliche Duplikat [Mocking Java Input] (http://stackoverflow.com/questions/6371379/mocking-java-inputstream) –

Antwort

1

Sie haben zwei Möglichkeiten. Stellen Sie entweder einige Testdateien bereit, die die erwarteten Fehler erzeugen, oder übergeben Sie den Stream an Eigenschaften-Retriever als Parameter. Statt des Parameters propertiesPath haben Sie also direkt inputStream (dieser Ansatz kann Ihr Problem einfach anderswo verschieben).

Wenn Sie sich entscheiden Strom als Parameter zu übergeben, gibt es einige Tipps, wie es verspotten: Mocking Java InputStream

+0

ich die mock von Input vergangen, aber noch Es löst keine IOException. Kann ich das irgendwie testen? – Jasmine

+0

Wird es eine gute Idee sein, wenn ich ArgumentCaptor verwenden, um die Inputstream.class zu erfassen und DoThrow (IOException.class) zu verwenden. Wenn (MockProperties) .load (ReqCaptor.capture()); und schließlich githubpropertiesRetreiver.loadPropertiesPath (filePath) aufrufen; und überprüfe die IOException? – Jasmine

1

Sie es tun können Sie Ihren Code ein wenig durch Refactoring. Das und verwenden Mockito oder eine andere Mockframework einen Inputstream zu erstellen, verhält sich wie gewünscht ein (werfen Ausnahmen):

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; 
} 

Sie Mockito zu create a partial mock Ihres Objekts verwenden können; Schein getIStream(String), um einen Schein InputStream zurückzugeben. Richten Sie den Mock so ein, dass die gewünschte Ausnahme ausgelöst wird, wenn InputStream::read(byte[]) aufgerufen wird. Wenn Sie die PowerMock nicht verwenden möchten, können Sie die Sichtbarkeit von getIStream(String) in default ändern. Dann Ebene Mockito wird die Arbeit machen:

@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

Ich versuche tatsächlich zu vermeiden, PowerMock oder Matchers.any() zu verwenden Ich plane, nur Mockito zu verwenden. – Jasmine

+0

Es wirft immer noch nicht die Ausnahme IOException oder IllegalArgumentException. Kann ich trotzdem einen beschädigten Inputstream erstellen? oder fehlt mir hier etwas? – Jasmine

+0

@Jasmine, können Sie die erforderliche Ausnahme in 'doThrow()' angeben. Ich habe in meinem Beispiel eine 'IllegalArgumentException' verwendet, aber Sie können auch' IOException' und seine Unterklassen oder irgendeine 'RuntimeException' auslösen. – Ralf

Verwandte Themen