2009-07-13 89 views
2

今天我遇到了非常困難的TDD問題。我需要通過HTTP POSTs與服務器交互。我找到了Apache Commons HttpClient,它可以滿足我的需求。與多個合作伙伴進行單元測試

然而,我結束了從Apache的百科全書一堆協作對象的:

public void postMessage(String url, String message) throws Exception { 

    PostMethod post = new PostMethod(url); 
    RequestEntity entity = new StringRequestEntity(message, 
             "text/xml; charset=ISO-8859-1"); 
    post.setRequestEntity(entity); 
    HttpClient httpclient = new HttpClient(); 
    try { 
     int result = httpclient.executeMethod(post); 

     System.out.println("Response status code: " + result); 
     System.out.println("Response body: "); 
     System.out.println(post.getResponseBodyAsString()); 
    } finally { 
     post.releaseConnection(); 
    } 
} 

我有一個PostMethod對象,RequestEntity對象和HttpClient對象。我覺得在依賴注入方面通過HttpClient相對比較舒服,但是我對其他合作者做了什麼?

我可以創建一堆工廠方法(或工廠類)創建的合作者,但我有點害怕,我會嘲笑太多。

跟進

感謝您的答案!我剩下的問題是這樣的方法:

public String postMessage(String url, String message) throws Exception { 

    PostMethod post = new PostMethod(url); 
    RequestEntity entity = new StringRequestEntity(message, 
             "text/xml; charset=ISO-8859-1"); 
    post.setRequestEntity(entity); 
    HttpClient httpclient = new HttpClient(); 
    httpclient.executeMethod(post); 
    return post.getResponseBodyAsString(); 
} 

如何正確地驗證返回值是post.getResponseBodyAsString()?我需要模擬post以及client嗎?

回答

4

簡答題:模擬HttpClient,不要模擬PostMethod或RequestEntity。

當然,這是一個判斷調用,但我建議先嘲笑真正需要嘲笑的事情:HttpClient。 PostMethod和RequestEntity是堆棧本地的,快速的和確定性的,我會讓它們保持原樣,如果有必要,你總是可以嘲笑它們。現在,通過嘲笑PostMethod和RequestEntity,您的代碼變得複雜,使用您的api的代碼變得複雜,並暴露您實現的細節。
隨着代碼的不斷髮展,您將會更好地瞭解需要嘲笑的內容,而無需現在就嘗試預測未來。

這可能是有用的:

http://www.testingreflections.com/node/view/7417

3

zielaj的回答是合理的,但你也可以創建具有以下簽名PostMethodFactory:

PostMethod getInstance(String url, String message, String contentType); 

...然後使用DI注入它和HttpClient。那麼你只有兩件事情可以嘲笑。

的PostMethodFactory可以這樣實現:

public PostMethod getInstance(String url, String content, String contentType, String charset) { 
    PostMethod post = new PostMethod(url); 
    RequestEntity entity = new StringRequestEntity(message, contentType, charset); 
    post.setRequestEntity(entity); 
    return post; 
}