2

今天我遇到了一个非常困难的 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对象。我觉得通过 ala 依赖注入比较舒服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

2 回答 2

4

简短的回答:模拟 HttpClient,不要模拟 PostMethod 或 RequestEntity。

当然这是一个判断调用,但我建议从模拟真正需要模拟的东西开始:HttpClient。PostMethod 和 RequestEntity 是堆栈本地的、快速的和确定性的,我会让它们保持原样,如有必要,您可以随时模拟它们。正如您现在的代码一样,通过模拟 PostMethod 和 RequestEntity,您使您的 api 复杂化,使使用您的 api 的代码复杂化,并公开您的实现细节。
随着代码的发展,您将更好地了解需要模拟什么,而无需现在尝试预测未来。

这可能有用:

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

于 2009-07-13T23:25:53.087 回答
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;
}
于 2009-07-13T23:27:33.740 回答