2011-04-06 63 views
3

嘿,一直在努力工作在最後一天左右,但擊中磚牆。試圖單元測試這段代碼。但不知道是否需要使用EasyMock?在網上看到一些例子,但似乎使用舊技術。關於URLConnection的JUnit測試,請使用EasyMock?

public boolean verifyConnection(final String url) { 
    boolean result; 

    final int timeout = getConnectionTimeout(); 
    if (timeout < 0) { 
     log.info("No need to verify connection to client. Supplied timeout = {}", timeout); 
     result = true; 
    } else { 
     try { 
      log.debug("URL: {} Timeout: {} ", url, timeout); 

      final URL targetUrl = new URL(url); 
      final HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection(); 

      connection.setConnectTimeout(timeout); 
      connection.connect(); 
      result = true; 
     } catch (ConnectException e) { 
      log.warn("Could not connect to client supplied url: " + url, e); 
      result = false; 
     } catch (MalformedURLException e) { 
      log.error("Malformed client supplied url: " + url, e); 
      result = false; 
     } catch (IOException e) { 
      log.warn("Could not connect to client supplied url: " + url, e); 
      result = false; 
     } 
    } 
    return result; 
} 

它只是需要在一個URL檢查其有效,如果你想嘲笑這個方法返回T或F.

+1

你想測試這種方法,或者你想測試其他東西,需要嘲笑這種方法的創新? – Ralph 2011-04-06 10:28:19

回答

2

我一直都認爲Mocking可以儘可能地避免,因爲它可能會導致難以維護JUnit測試並打敗整個目的。

我的建議是從JUnit本身在本地機器上創建一個臨時服務器。 在JUnit的開始,您可以使用Java套接字創建一個服務器(不超過10-15行需要的編碼),然後在您的代碼中傳遞本地服務器的URL。這樣你就可以減少嘲笑並確保最大的代碼覆蓋率。

事情是這樣的 -

public class SimpleServer extends Thread { 

public void run() { 
    try { 
     serverSocket = new ServerSocket(port); 

      while (true) { 
      Socket s = serverSocket.accept(); 
      } 
    } 
    catch (IOException e) { 
      e.printStackTrace(); 
    } 
    finally { 
     serverSocket = null; 
    } 
} 
} 
2

,我建議你通過在URL而不是字符串。沒有你的方法創建它需要的URL;讓客戶爲您創建URL並將其傳入。這樣,如果需要,您的測試可以替代模擬。

這幾乎是一個依賴注入的想法 - 你的方法應該給它的依賴關係,而不是自己創建它們。呼籲「新」是死亡的贈品。

這不是一個巨大的變化。你可以重載方法並有兩個簽名:一個接受一個URL字符串,另一個接受URL本身。第一種方法創建URL並調用第二個方法。這樣你就可以測試它,並且爲了方便起見,仍然在API中使用String簽名的方法。

2

試圖建立mock實現HttpURLConnection類的。像

public class MockHttpURLConnection extends HttpURLConnection {

加入法類重寫

' protected HttpURLConnection createHttpURLConnection(URL url) 
     throws IOException { 
    return (HttpURLConnection) url.openConnection(); 
} 

所以測試看起來像這樣:

@Test 
public void testGetContentOk() throws Exception 
{ 
    String url = "http://localhost"; 

    MockHttpURLConnection mockConnection = new MockHttpURLConnection(); 

    TestableWebClient client = new TestableWebClient(); 
    client.setHttpURLConnection(mockConnection); 

    boolean result = client.verify(url); 

    assertEquals(true, result); 
} 

@Test 
public void testDoesNotGetContentOk() throws Exception 
{ 
    String url = "http://1.2.3.4"; 

    MockHttpURLConnection mockConnection = new MockHttpURLConnection(); 

    TestableWebClient client = new TestableWebClient(); 
    client.setHttpURLConnection(mockConnection); 

    boolean result = client.verify(url); 

    assertEquals(false, result); 
} 

/** 
* An inner, private class that extends WebClient and allows us 
* to override the createHttpURLConnection method. 
*/ 
private class TestableWebClient extends WebClient1 { 

    private HttpURLConnection connection; 

    /** 
    * Setter method for the HttpURLConnection. 
    * 
    * @param connection 
    */ 
    public void setHttpURLConnection(HttpURLConnection connection) 
    { 
     this.connection = connection; 
    } 

    /** 
    * A method that we overwrite to create the URL connection. 
    */ 
    @Override 
    public HttpURLConnection createHttpURLConnection(URL url) throws IOException 
    { 
     return this.connection; 
    } 
} 

第一部分通過,但對於假僞測試得到真實,感謝回饋迄今爲止我找到的最佳網站的幫助。所以,讓我知道如果想在正確的軌道上

+0

戴夫,不要添加一個答案作爲你的問題的迴應。 – duffymo 2011-04-17 15:39:07