2016-04-29 4 views
0

Ich bin etwas neu zu Junit und Mockito und versuche zu verstehen, wie man Teile der Logik einer Klasse verspotten kann.Wie man JUnit und Mockito verwendet, um innere Logik zu verspotten

Ich habe eine Methode, die eine HTTP-Post und Get Call, aber es kann eine DB-Lookup sein. Wie kann ich die Antwort von dem HTTP-Aufruf in dieser Methode

BufferedReader in = new BufferedReader(new InputStreamReader(httpsConnection.getInputStream())); 
String inputLine; 
StringBuilder response = new StringBuilder(); 

while ((inputLine = in.readLine()) != null) { 
    response.append(inputLine); 
} 

Ich meine, es muss eine Möglichkeit, meine Logik zu testen, ohne zu echtem http Aufruf zu tun oder db-Lookup oder was auch immer verspotten.

// HTTP GET request 
public String sendGet(URL url) throws Exception { 

    s_logger.debug("URL: " + url); 
    HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection(); 

    // Add request header 
    httpsConnection.setRequestMethod("GET"); 
    httpsConnection.setRequestProperty("Content-Type", "application/xml"); 

    if (sessionId != null) { 
     httpsConnection.setRequestProperty("sessionId", sessionId); 
    } else { 
     httpsConnection.setRequestProperty("username", ACCOUNT_USERNAME); 
     httpsConnection.setRequestProperty("password", ACCOUNT_PASSWORD); 
    } 

    httpsConnection.setInstanceFollowRedirects(false); 
    httpsConnection.setUseCaches(false); 

    // Print Request Header 
    s_logger.debug("Request Header: " + httpsConnection.getRequestProperties()); 

    int responseCode = httpsConnection.getResponseCode(); 
    s_logger.debug("Response Code : " + responseCode); 

    Map<String, List<String>> headerFields = httpsConnection.getHeaderFields(); 
    s_logger.debug("Response Header: " + headerFields); 

    BufferedReader in = new BufferedReader(new InputStreamReader(httpsConnection.getInputStream())); 
    String inputLine; 
    StringBuilder response = new StringBuilder(); 

    while ((inputLine = in.readLine()) != null) { 
     response.append(inputLine); 
    } 
    in.close(); 

    // Set Session ID 
    final String SESSION_KEY = "sessionId"; 
    if (this.sessionId == null && httpsConnection.getHeaderFields().containsKey(SESSION_KEY)) { 
     this.sessionId = httpsConnection.getHeaderFields().get(SESSION_KEY).get(0); 
     s_logger.debug("SESSION ID : " + this.sessionId); 
    } 

    // print result 
    s_logger.debug("RESPONSE: " + response.toString()); 
    return response.toString(); 
} 

Vielen Dank für jede Hilfe oder Anregung.

UPDATE: Ich habe eine Art von das wurde vorgeschlagen, aber ich bin mir nicht sicher, ob das Sinn macht, auch ich mag nicht die Tatsache, dass diese Methoden jetzt öffentlich sind.

final URL url = new URL("https://test.com"); 
    final String request = "Test"; 
    HttpsURLConnection httpsConnection = mock(HttpsURLConnection.class); 


    final HttpConnectionClient httpSpy = spy(new HttpConnectionClient()); 
    Mockito.doReturn(httpsConnection).when(httpSpy).getConnection(url); 
    Mockito.doNothing().when(httpSpy).sendRequest(httpsConnection, request); 
    Mockito.doReturn(response).when(httpSpy).createBufferReader(httpsConnection); 

    assertEquals(response,httpSpy.sendPost(url, request)); 
+0

Sie arbeiten mit lokaler URL? –

+0

Nein, ich rufe einen Remote-Service an – FreshMike

+0

Trennen Sie die "create connection" -Logik von der "read" -Logik und testen Sie sie einzeln. – chrylis

Antwort

2

Ein Hack wird mit Spione und Paket-lokalen Methoden:

public class MyClass { 
    public void myMethod() { 
     //stuff 
     stuffThatNeedsStubbing(); 
     //more stuff 
    } 

    void stuffThatNeedsStubbing() { 
     //stuff that needs stub 
    } 
} 

public class MyClassTest { 
    @Test 
    public void example() { 
     final MyClass myClass = spy(new MyClass()); 
     doNothing().when(myClass).stuffThatNeedsStubbing(); 
     myClass.myMethod(); 
    } 
} 

In Ihrem Fall Sie eine Paket-local-Methode BufferedReader createBufferedReader() schaffen könnte, und dies in Ihrem Test mit einem Mock ersetzen.

0

Das einzige knifflige Bit ist die url.openConnection(), weil die URL finale Klasse ist, so dass Sie es nicht verspotten können. Wenn Sie es trennen, können Sie mock(HttpsURLConnection.class) mit Mockito verwenden und z. ByteArrayInputStream für die getInputStream() mit Scheinergebnis.