我正在尝试构建一个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*/)
答案 0 :(得分:25)
按照以下步骤可能会有所帮助:
1.mock it(ex.cileito)
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);
答案 1 :(得分:1)
我想创建一个具体的CloseableHttpResponse而不是mock,所以我在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" (!)基本上将visiblity颠覆为public并为构造函数提供null连接处理程序。
现在我可以使用
实例化具体的CloseableHttpResponseCloseableHttpResponse response = new PublicHttpResponseProxy(basicResponse);
通常的警告适用。由于代理是受包保护的,因此它不是官方API的一部分,因此您可能正在滚动它以后将无法使用的骰子。另一方面,它并不多,所以你可以轻松地编写自己的版本。会有一些剪切和粘贴,但它不会那么糟糕。
答案 2 :(得分:1)
自问这个问题以来已经有一段时间了,但我想提供一个我用过的解决方案。
我创建了一个扩展BasicHttpResponse
类的小类,并实现了CloseableHttpResponse
接口(除了关闭响应的方法之外)。由于BasicHttpResponse
类包含几乎所有内容的setter方法,因此我可以使用以下代码设置所需的所有字段:
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;
}
我基本上设置了实际代码使用的所有字段。这还包括将模拟响应内容从文件读取到流中。
答案 3 :(得分: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 { }
}
答案 4 :(得分:0)
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;
}
答案 5 :(得分: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);