当前位置: 首页 > 知识库问答 >
问题:

Mockito doReturn/When执行real方法(没有CGILIB)

孙和安
2023-03-14
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.mockito.Mockito.*;

public class SpyTest {
    HttpClient httpClient;
    private HttpResponse httpResponse;
    private StatusLine responseStatus;
    private HttpEntity responseEntity;

    @BeforeMethod
    public void setupClient() throws Exception {
        List spy = spy(new ArrayList());
        doReturn(true).when(spy).addAll(any(Collection.class)); // this works!

        DefaultHttpClient directClient = new DefaultHttpClient();
        httpClient = spy(directClient);
        httpResponse = mock(HttpResponse.class);
        responseStatus = mock(StatusLine.class);
        responseEntity = mock(HttpEntity.class);
        doReturn(responseStatus).when(httpResponse).getStatusLine();
        doReturn(responseEntity).when(httpResponse).getEntity();
        doReturn(httpResponse).when(httpClient).execute(any(HttpPost.class)); // failing here
    }

    @Test
    public void itShouldSetupTheSpy() throws Exception {
        doReturn(200).when(responseStatus).getStatusCode();
        doReturn("OK").when(responseStatus).getReasonPhrase();
        doAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                OutputStream os = (OutputStream) invocation.getArguments()[0];
                os.write("{\"id\": 100}".getBytes());
                return null;
            }
        }).when(responseEntity).writeTo(any(OutputStream.class));
    }
}
    java.lang.IllegalArgumentException: Request must not be null.
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:801)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
    at SpyTest.setupClient(SpyTest.java:37)

    [INFO] +- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.3:compile
    [INFO] |  \- org.codehaus.jackson:jackson-core-asl:jar:1.9.3:compile
    [INFO] +- org.testng:testng:jar:6.8:test
    [INFO] |  +- junit:junit:jar:4.10:test
    [INFO] |  |  \- org.hamcrest:hamcrest-core:jar:1.1:test
    [INFO] |  +- org.beanshell:bsh:jar:2.0b4:test
    [INFO] |  +- com.beust:jcommander:jar:1.27:test
    [INFO] |  \- org.yaml:snakeyaml:jar:1.6:test
    [INFO] +- org.mockito:mockito-all:jar:1.9.5:test
    [INFO] +- com.newrelic:newrelic-api:jar:2.3.0:compile
    [INFO] +- org.apache.httpcomponents:httpclient:jar:4.2.5:compile
    [INFO] |  +- org.apache.httpcomponents:httpcore:jar:4.2.4:compile
    [INFO] |  +- commons-logging:commons-logging:jar:1.1.1:compile
    [INFO] |  \- commons-codec:commons-codec:jar:1.6:compile
    [INFO] \- org.apache.commons:commons-lang3:jar:3.1:compile

看起来HttpClient及其子类有问题。

共有1个答案

澹台奇略
2023-03-14

execute是final方法,Mockito不能模拟final方法(如关于间谍活动和FAQ的一节所述)。

为什么?由于在正常情况下不能重写final方法,Java采取了一种快捷方式,将调用(对final方法的调用)直接编译到实现中,而不是在Java等效的虚拟方法表中查找它们。这意味着Mockito永远不会参与最终的方法调用,因此不能拦截行为,甚至不能接收stubbing/verification调用。

您可以切换到模仿并使用原始HttpClient吗?您可以模拟接口的任何方法,而不必担心可见性或最终方法问题。

 类似资料:
  • 目前我正在为学校做一个项目,下面是要求: 编写一个Temperature类,它将保持以华氏为单位的温度,并提供获取以华氏、摄氏度和开尔文为单位的温度的方法。该类应具有以下字段: :保持华氏温度的倍增器。 该类应具有以下方法: :构造函数接受华氏温度(双倍)并将其存储在ftemp字段中。 :set Fahrenheit方法接受一个华氏温度(作为双值),并将其存储在ftemp字段中。 :返回ftemp

  • 我正在尝试测试一个空数据库/没有从数据库返回任何内容的场景。 我用mockito写了一个junit4测试类。有一个服务类和dao类是由mockito创建的。首先,我定义了“何时”方法,它起作用了。后来,我试着调用“when”方法,看看会发生什么,不管怎样,它工作了。为什么? 当myService.getDistinctObjectList()被调用时,myService类会调用myDao的所有四个

  • 问题内容: 我有一个多模块Maven项目,其中一个模块用于分发。 该发行版包含一个我想轻松执行的可执行jar。但是,要执行它,我必须键入类似以下内容: 简单键入以下内容将是更好的选择: 不幸的是,我找不到找到执行.jar的java目标的方法。exec目标实际上可以做到,但是有一个陷阱:jar包含一个嵌入式码头服务器,并且由于exec的工作方式(不使用与maven相同的JVM),除非我杀死进程,否则

  • 所以我用这个mock(potatoConsumer)订阅,rxJava调用了“accept”,mockito将其标记为交互,但mockito认为这个交互不是我所期望的,为什么? 图书馆的版本使用了她: 一些由powermock模拟的字段在“验证”时失败,但由mockito模拟的字段不是 Mockito不能模拟未打开的字段,没有,但Mockito与Powermock maker inline冲突 P

  • 我正在开发一个java程序,它接受输入的分数,给出输入的总数和平均值,但是我很难计算出如何获得当前输入的最高分数“我使用了大量嵌套的else-if语句,但必须有一种简单的方法来实现这一点,而不是键入100个else-if语句这是我的代码。我在else-if语句开始的地方添加了一条注释,以确定最高级别