22

単体テストの 1 つで返されるCloseableHttpResponseモック オブジェクトを構築しようとしていますが、コンストラクターがありません。このDefaultHttpResponseFactoryを見つけましたが、HttpResponse しか作成しません。CloseableHttpResponse を構築する簡単な方法は何ですか? execute()テストを呼び出してから and を設定する必要がstatusLineありentityますか? それは奇妙なアプローチのようです。

私がモックしようとしている方法は次のとおりです。

public static CloseableHttpResponse getViaProxy(String url, String ip, int port, String username,
                                                String password) {
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(
            new AuthScope(ip, port),
            new UsernamePasswordCredentials(username, password));
    CloseableHttpClient httpclient = HttpClients.custom()
            .setDefaultCredentialsProvider(credsProvider).build();
    try {
        RequestConfig config = RequestConfig.custom()
                .setProxy(new HttpHost(ip, port))
                .build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(config);

        LOGGER.info("executing request: " + httpGet.getRequestLine() + " via proxy ip: " + ip + " port: " + port +
                " username: " + username + " password: " + password);

        CloseableHttpResponse response = null;
        try {
            return httpclient.execute(httpGet);
        } catch (Exception e) {
            throw new RuntimeException("Could not GET with " + url + " via proxy ip: " + ip + " port: " + port +
                    " username: " + username + " password: " + password, e);
        } finally {
            try {
                response.close();
            } catch (Exception e) {
                throw new RuntimeException("Could not close response", e);
            }
        }
    } finally {
        try {
            httpclient.close();
        } catch (Exception e) {
            throw new RuntimeException("Could not close httpclient", e);
        }
    }
}

PowerMockito を使用したモック コードは次のとおりです。

    mockStatic(HttpUtils.class);
    when(HttpUtils.getViaProxy("http://www.google.com", anyString(), anyInt(), anyString(), anyString()).thenReturn(/*mockedCloseableHttpResponseObject goes here*/)
4

6 に答える 6

36

次の手順に従ってください。

1.モックする(例:mockito)

CloseableHttpResponse response = mock(CloseableHttpResponse.class);
HttpEntity entity = mock(HttpEntity.class);

2.いくつかのルールを適用する

when(response.getStatusLine()).thenReturn(new BasicStatusLine(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "FINE!"));
when(entity.getContent()).thenReturn(getClass().getClassLoader().getResourceAsStream("result.txt"));
when(response.getEntity()).thenReturn(entity);

3.使う

when(httpClient.execute((HttpGet) any())).thenReturn(response);
于 2014-01-20T09:17:51.863 に答える
4

この質問が出されてからしばらく経ちましたが、私が使用した解決策を提供したいと思います。

BasicHttpResponseクラスを拡張し、インターフェイスを実装する小さなクラスを作成しましたCloseableHttpResponse(応答を閉じるメソッドしかありません)。このBasicHttpResponseクラスにはほとんどすべてのセッター メソッドが含まれているため、次のコードで必要なすべてのフィールドを設定できます。

public static CloseableHttpResponse buildMockResponse() throws FileNotFoundException {
    ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1);
    String reasonPhrase = "OK";
    StatusLine statusline = new BasicStatusLine(protocolVersion, HttpStatus.SC_OK, reasonPhrase);
    MockCloseableHttpResponse mockResponse = new MockCloseableHttpResponse(statusline);
    BasicHttpEntity entity = new BasicHttpEntity();
    URL url = Thread.currentThread().getContextClassLoader().getResource("response.txt");
    InputStream instream = new FileInputStream(new File(url.getPath()));
    entity.setContent(instream);
    mockResponse.setEntity(entity);
    return mockResponse;
}

基本的に、実際のコードで使用されるすべてのフィールドを設定します。これには、ファイルからストリームへのモック応答コンテンツの読み取りも含まれます。

于 2015-08-21T14:53:46.507 に答える
2

モックではなく具体的​​な CloseableHttpResponse も作成したかったので、Apache HTTP クライアントのソース コードでそれを追跡しました。

MainClientExecでは、execute からのすべての戻り値は次のようになります。

return new HttpResponseProxy(response, connHolder);

ここで、connHolder は null にすることができます。

HttpResponseProxyは、connHolder を閉じる薄いラッパーです。残念ながら、これはパッケージで保護されているため、(必ずしも) 表示されません。

私がしたことは、「PublicHttpResponseProxy」を作成することでした

package org.apache.http.impl.execchain;

import org.apache.http.HttpResponse;

public class PublicHttpResponseProxy extends HttpResponseProxy {

    public PublicHttpResponseProxy(HttpResponse original) {
        super(original, null);
    }
}

パッケージ "org.apache.http.impl.execchain" に含まれている必要があります (!) 基本的に、可視性を public にバンプし、コンストラクターに null 接続ハンドラーを提供します。

これで、具体的な CloseableHttpResponse をインスタンス化できます

CloseableHttpResponse response = new PublicHttpResponseProxy(basicResponse);

通常の警告が適用されます。プロキシはパッケージで保護されているため、公式の API の一部ではありません。一方、それほど多くはないので、独自のバージョンを簡単に作成できます。多少の切り貼りはありますが、それほど悪くはありません。

于 2015-01-28T23:13:45.880 に答える
1

nvm、私はそれを使ってそれをハッキングすることになりましたexecute():

private CloseableHttpResponse getMockClosesableHttpResponse(HttpResponse response) throws Exception {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse closeableHttpResponse = httpClient.execute(new HttpGet("http://www.test.com"));
    closeableHttpResponse.setEntity(response.getEntity());
    closeableHttpResponse.setStatusLine(response.getStatusLine());
    return closeableHttpResponse;
}
于 2013-11-07T22:26:34.363 に答える
1

既存の BasicHttpResponse タイプに便乗してテスト実装を作成するだけで十分簡単です。

public class TestCloseableHttpResponse extends BasicHttpResponse implements CloseableHttpResponse {

    public TestCloseableHttpResponse(StatusLine statusline, ReasonPhraseCatalog catalog, Locale locale) {
        super(statusline, catalog, locale);
    }

    public TestCloseableHttpResponse(StatusLine statusline) {
        super(statusline);
    }

    public TestCloseableHttpResponse(ProtocolVersion ver, int code, String reason) {
        super(ver, code, reason);
    }


    @Override
    public void close() throws IOException { }

}
于 2020-03-04T20:56:18.910 に答える
0

これは私のために働いた:

HttpEntity httpEntity = mock(HttpEntity.class); // mocked

CloseableHttpResponse closeableHttpResponse = mock(CloseableHttpResponse.class) // mocked

CloseableHttpClient closeableHttpClient = mock(CloseableHttpClient .class) // mocked

String resultJson =
    "{\"key\": \"value\"}";

InputStream is = new ByteArrayInputStream( resultJson.getBytes() );

Mockito.when(httpEntity.getContent()).thenReturn(is);
Mockito.when( httpEntity.getContentLength() ).thenReturn(Long.valueOf(.length()));
StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, "success");
Mockito.when(httpEntity.toString()).thenReturn(resultJson);
Mockito.when(closeableHttpResponse.getEntity()).thenReturn(httpEntity);
Mockito.when(closeableHttpResponse.getStatusLine()).thenReturn(statusLine);

Mockito.when(closeableHttpClient.execute((HttpPost) 
Mockito.any())).thenReturn(closeableHttpResponse);
于 2021-07-06T18:35:52.160 に答える