与多个合作者进行单元测试 [英] Unit testing with multiple collaborators

查看:21
本文介绍了与多个合作者进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我遇到了一个非常困难的 TDD 问题.我需要通过 HTTP POST 与服务器交互.我找到了 Apache Commons HttpClient,它可以满足我的需求.

Today I ran into a very difficult TDD problem. I need to interact with a server through HTTP POSTs. I found the the Apache Commons HttpClient, which does what I need.

然而,我最终得到了一堆来自 Apache Commons 的协作对象:

However, I end up with a bunch of collaborating objects from 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 依赖注入我感觉比较舒服,但是我对其他协作者怎么办?

I have a PostMethod object, a RequestEntity object and a HttpClient object. I feel relatively comfortable passing in the HttpClient ala dependency injection, but what do I do about the other collaborators?

我可以创建一堆工厂方法(或一个工厂类)来创建协作者,但我有点担心我会嘲笑太多.

I could create a bunch of factory methods (or a factory class) to create the collaborators, but I'm a bit afraid that I'd be mocking too much.

感谢您的回答!我剩下的问题是这样的方法:

Thanks for the answers! My remaining issue is a method like this:

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?

How do I correctly verify that the returned value is from post.getResponseBodyAsString()? Would I have to mock post as well as client?

推荐答案

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

Short answer: mock HttpClient, don't mock PostMethod or RequestEntity.

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

Of course this is a judgement call, but I'd suggest start with mocking things that really need to be mocked: HttpClient. PostMethod and RequestEntity are stack-local, fast, and deterministic, I'd leave them as they are, you can always mock them later if necessary. As your code is now, by mocking PostMethod and RequestEntity you complicate your api, complicate the code that uses your api, and expose the details of your implementation.
As your code evolves, you'll have a better idea what needs to be mocked, no need to try to predict the future now.

这可能有用:

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

这篇关于与多个合作者进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆