2016-04-29 99 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()与模拟结果。

相关问题