【问题标题】:Unit testing with multiple collaborators与多个协作者进行单元测试
【发布时间】:2009-07-13 22:38:33
【问题描述】:

今天我遇到了一个非常困难的 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()?我需要模拟postclient 吗?

【问题讨论】:

    标签: java unit-testing http tdd apache-commons


    【解决方案1】:

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

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

    这可能有用:

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

    【讨论】:

      【解决方案2】:

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 2023-01-10
        • 1970-01-01
        • 2018-04-20
        • 2018-05-13
        • 1970-01-01
        • 1970-01-01
        • 2010-10-10
        • 2020-05-07
        • 1970-01-01
        相关资源
        最近更新 更多