gpt4 book ai didi

java - Mockito doReturn/when 执行真正的方法(没有CGILIB)

转载 作者:行者123 更新时间:2023-11-30 08:27:55 44 4
gpt4 key购买 nike

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

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)

我相信我已经关注了the official advice !密切关注,就像我的其他 spy 一样。和 this answer !似乎不适用于我,因为我不使用 CGLIB,从 Maven 依赖树可以看出:

    [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 及其子类有问题。

最佳答案

execute 是一个 final method , Mockito 不能模拟 final 方法(如 the section on spyingthe FAQ 中所述)。

为什么?因为在正常情况下您不能覆盖 final方法,所以 Java 采取了一种快捷方式并将(对 final方法的)调用直接编译到实现而不是在 Java's equivalent of a virtual method table 中查找它们。 .这意味着 Mockito 永远不会参与 final方法调用,因此无法拦截行为,甚至无法接收 stub /验证调用。

你能切换到模拟和使用 a raw HttpClient反而?您可以模拟接口(interface)的任何方法,而不必担心可见性或 final方法问题。

关于java - Mockito doReturn/when 执行真正的方法(没有CGILIB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20528472/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com