私は、ユニットテストの1つで返される CloseableHttpResponse モックオブジェクトを作成しようとしていますが、そのコンストラクタがありません。私はこれを見つけました DefaultHttpResponseFactory ですが、それはHttpResponseを作成するだけです。 CloseableHttpResponseを作成する簡単な方法は何ですか?テストでexecute()
を呼び出してから、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*/)
次の手順に従ってください。
1. mock it(例: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);
この質問が出されて久しぶりですが、使用したソリューションを提供したいと思います。
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;
}
基本的に、実際のコードで使用されるすべてのフィールドを設定します。これには、ファイルからストリームへの模擬応答コンテンツの読み取りも含まれます。
私もモックではなく具体的な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の一部ではないため、後で使用できないようにサイコロを振っている可能性があります。一方、それほど多くはないので、独自のバージョンを簡単に作成できます。カットアンドペーストがあるかもしれませんが、それほど悪くはありません。
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;
}
既存の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 { }
}