Mockito doReturn/当执行真实方法时(没有CGILIB)



我做了很多Mockito间谍,只是在一个新项目中模仿我自己的工作示例。但这次惨败

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.IollegalArgumentException:请求不能为null。网址:org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:801)网址:org.apache.http.impl.client.AbstractHttpClient.exexecute(AbstractHttpClient.java:784)位于SpyTest.setupClient(SpyTest.java:37)

我相信我听从了官方的建议!就像我的其他间谍一样。这个答案!似乎不适用于我,因为我没有使用CGLIB,这从maven依赖树中可以明显看出:

[信息]+-org.codehaus.jackson:jackson mapper asl:jar:1.9.3:编译[信息]|\-org.codehaus.jackson:jackson核心asl:jar:1.9.3:编译[信息]+-org.testng:testng:jar:6.8:test[信息]|+-junit:junit:jar:4.10:测试[信息]||\-org.hamcrest:hamcrest-core:jar:1.1:test[信息]|+-org.beanshell:bsh:jar:2.0b4:测试[信息]|+-com.beust:jcommander:jar:1.27:test[信息]|\-org.yaml:snakeyaml:jar:1.6:test[信息]+-org.mockito:mmockito-all:jar:1.9.5:测试[信息]+-com.newreliet:newrelie-api:jar:2.3.0:编译[信息]+-org.apache.httpcomponents:httpclient:jar:4.2.5:编译[信息]|+-org.apache.httpcomponents:httpcore:jar:4.2.4:编译[信息]|+-commons日志:commons日志记录:jar:1.1.1:编译[信息]|\-commons编解码器:commons编解码:jar:1.6:compile[信息]\-org.apache.commons:commons-lang3:jar:3.1:compile

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

execute是一个最终方法,Mockito不能模拟最终方法(如间谍部分和常见问题解答中所述)。

为什么?因为在正常情况下不能覆盖final方法,所以Java采用了一种快捷方式,直接编译对实现的调用(对final方法的调用),而不是在Java的虚拟方法表中查找它们。这意味着Mockito从未参与最终的方法调用,因此无法拦截行为,甚至无法接收存根/验证调用。

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

相关内容

  • 没有找到相关文章