簡體   English   中英

Mockito doReturn /何時執行實數方法(不使用CGILIB)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM