【问题标题】:Why does my Mockito mock object use real the implementation为什么我的 Mockito 模拟对象使用真实的实现
【发布时间】:2010-12-28 17:16:19
【问题描述】:

我在模拟 Apache Http 客户端时遇到了问题。以下尝试创建模拟:

DefaultHttpClient httpClient = Mockito.mock(DefaultHttpClient.class);

无法创建真正的模拟。上面的行毫无例外地被执行,但是当我尝试存根一些行为时:

Mockito.when(httpClient.execute(Mockito.<HttpUriRequest>anyObject())).thenReturn(null);

我从 AbstractHttpClient 中的一个方法中得到一个异常:

Exception in thread "main" java.lang.IllegalArgumentException: Request must not be null.
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:572)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)

为什么要在 Mockito.when 中执行的调用传递给 AbstractHttpClient?

我找到了解决这个特定问题的方法:使用接口 HttpClient 而不是尝试模拟具体的子类。在这种情况下,这是一个更好的解决方案,但我想知道这里发生了什么?为什么我不能用 Mockito 正确地模拟这个具体的类? DefaultHttpClient 有什么特别之处吗?是否还有其他 Mockito 无法模拟具体类的情况?

我在 OSX 上使用 Mockito 1.8.5、Apache httpclient 4.0.3、Apache http core 4.1、JDK 1.6.0

【问题讨论】:

    标签: java unit-testing apache mocking mockito


    【解决方案1】:

    AbstractHttpClient 上的一些方法是最终的,因此不会被模拟。 IMO,这种行为是不模拟具体类的第一大理由。

    【讨论】:

    【解决方案2】:

    试试这个语法(只是一个示例,不是真正的代码):

    import static Mockito.*;
    // ...
    HttpClient httpClient = mock(HttpClient.class);
    doReturn(null).when(httpClient).execute(anyObject()).
    

    请参阅此链接以更好地解释问题/解决方案:http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#doReturn(java.lang.Object)

    【讨论】:

    • 正如我上面提到的,模拟 HttpClient 接口是可行的,问题在于具体类 DefaultHttpClient。在这种情况下,当然建议模拟接口而不是默认实现。我只是好奇为什么嘲笑不起作用;有时你必须模拟具体的类,然后这些知识就会变得有用。
    • 如果您的代码是这样做的,您仍然无法覆盖 HttpClient 的静态创建。即 HttpClients.createDefault()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多