2016-04-29 100 views
0

我對Junit和Mockito來說很陌生,並試圖理解如何模擬某個類的邏輯部分。如何使用JUnit和Mockito來模擬內部邏輯

我有一個方法,做一個HTTP POST和獲得調用,但它可能是一個數據庫查找。如何嘲笑從HTTP調用這個方法

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

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

響應我的意思是有一定的方式來考驗我的邏輯沒有做實際HTTP調用或數據庫查找或什麼的。

// 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(); 
} 

感謝您的任何幫助或建議。

更新: 我做了那種建議,但我不知道這是否有道理,我也不喜歡這些方法現在是公開的事實。

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

你正在使用本地URL? –

+0

不,我正在調用遠程服務 – FreshMike

+0

將「創建連接」邏輯與「讀取」邏輯分開並單獨進行測試。 – chrylis

回答

2

一個黑客利用間諜和包本地方法:

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

在你的情況,你可以創建一個包,本地方法BufferedReader createBufferedReader(),並在你的測試模擬替換此。

0

唯一棘手的是url.openConnection(),因爲URL是final類,所以你不能嘲笑它。如果您將它分開,那麼您可以使用mockito使用mock(HttpsURLConnection.class)並提供例如ByteArrayInputStreamgetInputStream()與模擬結果。

相關問題