![](/img/trans.png)
[英]Mockito doReturn() executes the Real function instead of just return
[英]Mockito doReturn/when executes real method (without 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.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)
相信我已经听从了官方的建议 ! 像其他间谍一样紧密 而这个答案 ! 似乎不适用于我,因为我没有使用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
是最终方法 ,而Mockito无法模拟最终方法(如有关间谍的部分以及FAQ所述 )。
为什么? 由于在正常情况下您无法覆盖最终方法,因此Java采用快捷方式并将调用(对最终方法)直接编译为实现,而不是在Java的等效虚拟方法表中查找它们。 这意味着Mockito永远不会参与最终方法调用,因此无法拦截行为,甚至无法接收存根/验证调用。
您可以切换到模拟并使用原始的HttpClient吗? 您可以模拟接口的任何方法,而不必担心可见性或最终方法问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.