今天我遇到了一个非常困难的TDD问题。我需要通过HTTP POST与服务器进行交互。我找到了Apache Commons HttpClient,它可以满足我的需要。
但是,我最终得到了来自Apache Commons的一堆协作对象:
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
ala依赖注入感觉相对舒服,但我该如何处理其他协作者呢?
我可以创建一堆工厂方法(或工厂类)来创建协作者,但我有点害怕我会嘲笑太多。
感谢您的回答!我剩下的问题是这样的方法:
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
?
答案 0 :(得分:4)
简短回答:模拟HttpClient,不要模拟PostMethod或RequestEntity。
当然这是一个判断调用,但我建议从嘲笑真正需要嘲笑的事情开始:HttpClient。 PostMethod和RequestEntity是堆栈本地的,快速的和确定性的,我会保留它们,如果有必要,你可以随后嘲笑它们。正如您的代码现在一样,通过模拟PostMethod和RequestEntity,您会使api复杂化,使用api的代码变得复杂,并公开实现的详细信息。
随着您的代码的发展,您将更好地了解需要嘲笑的内容,无需尝试预测未来。
这可能有用:
答案 1 :(得分: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;
}