如何模拟 HttpClient class 到 return 不同的响应
How to mock HttpClient class to return different responses
如何使 Mockito return 不同的 HttpEntity 值以响应不同的 URI?
测试将使用 mockHttpClient 发出多个 HTTP 请求(所有请求都是 POST 请求)。
HttpEntity httpEntity = EntityBuilder.create().setText(response).build();
PowerMockito.when(response, "getEntity").thenReturn(httpEntity);
而测试本身是这样设计的:
CloseableHttpClient client = mockHttpClient(200, HTTP_ENTITY);
runTest();
Mockito.verify(client, Mockito.times(2)).execute(Mockito.any());
对于上述 return 个不同 HTTP 实体的测试,我尝试了以下方法:
CloseableHttpClient client = Mockito.mock(CloseableHttpClient.class);
Mockito.when(client.execute(new HttpPost("http://127.0.0.1:8000/new/a"))).thenReturn(resp1);
Mockito.when(client.execute(new HttpPost("http://127.0.0.1:8000/new/a/b"))).thenReturn(resp2);
但我无法构建不同的 http 实体并根据请求中的 URI 获得响应。
首先,在这种情况下不需要 Powermock
。您不需要模拟静态方法、构造函数或任何其他讨厌的东西。
我准备了一个小示例测试,它对我来说开箱即用 Mockito 2.23.4
,你可以看到断言 isSameAs
("Verifies that the actual value is the same as the given one, ie using == comparison.") 真正检查某个 POST
调用是否与先前模拟的响应相匹配:
public class CloseableHttpClientTest {
private final CloseableHttpClient client = mock(CloseableHttpClient.class);
@Test
public void mockClient() throws IOException {
// given
CloseableHttpResponse resp1 = mock(CloseableHttpResponse.class);
CloseableHttpResponse resp2 = mock(CloseableHttpResponse.class);
HttpPost post1 = new HttpPost("http://127.0.0.1:8000/new/a");
HttpPost post2 = new HttpPost("http://127.0.0.1:8000/new/a/b");
when(client.execute(post1)).thenReturn(resp1);
when(client.execute(post2)).thenReturn(resp2);
// when
CloseableHttpResponse returnedResp1 = client.execute(post1);
CloseableHttpResponse returnedResp2 = client.execute(post2);
// then
assertThat(returnedResp1).isSameAs(resp1);
assertThat(returnedResp2).isSameAs(resp2);
verify(client).execute(post1);
verify(client).execute(post2);
}
}
谢谢你。
您的回复帮助我了解了如何更好地构建测试。但在这种情况下,我试图在不进行任何重组的情况下修改一个。
我想我会 post 在这里回答,以防万一其他人正在寻找答案。
Mockito.doAnswer(new Answer<CloseableHttpResponse>() {
@Override
public CloseableHttpResponse answer(InvocationOnMock invocation) {
CloseableHttpResponse httpResponse = Mockito.mock(CloseableHttpResponse.class);
// No change to status code based on endpoints
Mockito.when(status.getStatusCode()).thenReturn(withResponseCode);
Mockito.when(httpResponse.getStatusLine()).thenReturn(status);
HttpEntity entity = Mockito.mock(HttpEntity.class);
Object[] args = invocation.getArguments();
String endpoint = ((HttpPost) args[0]).getURI().getPath();
if (endpoint.contains("/a/b")) {
entity = EntityBuilder.create().setText("something").build();
Mockito.when(httpResponse.getEntity()).thenReturn(entity);
} else {
entity = EntityBuilder.create().setText("something else").build();
Mockito.when(httpResponse.getEntity()).thenReturn(entity);
}
return httpResponse;
}
}).when(client).execute(Mockito.any(HttpUriRequest.class));
集成测试不会测试其余客户端本身,我不需要旋钮和多个模拟客户端来进行不同的响应。以上内容帮助我根据接收请求的端点返回不同的响应。
如何使 Mockito return 不同的 HttpEntity 值以响应不同的 URI?
测试将使用 mockHttpClient 发出多个 HTTP 请求(所有请求都是 POST 请求)。
HttpEntity httpEntity = EntityBuilder.create().setText(response).build();
PowerMockito.when(response, "getEntity").thenReturn(httpEntity);
而测试本身是这样设计的:
CloseableHttpClient client = mockHttpClient(200, HTTP_ENTITY);
runTest();
Mockito.verify(client, Mockito.times(2)).execute(Mockito.any());
对于上述 return 个不同 HTTP 实体的测试,我尝试了以下方法:
CloseableHttpClient client = Mockito.mock(CloseableHttpClient.class);
Mockito.when(client.execute(new HttpPost("http://127.0.0.1:8000/new/a"))).thenReturn(resp1);
Mockito.when(client.execute(new HttpPost("http://127.0.0.1:8000/new/a/b"))).thenReturn(resp2);
但我无法构建不同的 http 实体并根据请求中的 URI 获得响应。
首先,在这种情况下不需要 Powermock
。您不需要模拟静态方法、构造函数或任何其他讨厌的东西。
我准备了一个小示例测试,它对我来说开箱即用 Mockito 2.23.4
,你可以看到断言 isSameAs
("Verifies that the actual value is the same as the given one, ie using == comparison.") 真正检查某个 POST
调用是否与先前模拟的响应相匹配:
public class CloseableHttpClientTest {
private final CloseableHttpClient client = mock(CloseableHttpClient.class);
@Test
public void mockClient() throws IOException {
// given
CloseableHttpResponse resp1 = mock(CloseableHttpResponse.class);
CloseableHttpResponse resp2 = mock(CloseableHttpResponse.class);
HttpPost post1 = new HttpPost("http://127.0.0.1:8000/new/a");
HttpPost post2 = new HttpPost("http://127.0.0.1:8000/new/a/b");
when(client.execute(post1)).thenReturn(resp1);
when(client.execute(post2)).thenReturn(resp2);
// when
CloseableHttpResponse returnedResp1 = client.execute(post1);
CloseableHttpResponse returnedResp2 = client.execute(post2);
// then
assertThat(returnedResp1).isSameAs(resp1);
assertThat(returnedResp2).isSameAs(resp2);
verify(client).execute(post1);
verify(client).execute(post2);
}
}
谢谢你。 您的回复帮助我了解了如何更好地构建测试。但在这种情况下,我试图在不进行任何重组的情况下修改一个。
我想我会 post 在这里回答,以防万一其他人正在寻找答案。
Mockito.doAnswer(new Answer<CloseableHttpResponse>() {
@Override
public CloseableHttpResponse answer(InvocationOnMock invocation) {
CloseableHttpResponse httpResponse = Mockito.mock(CloseableHttpResponse.class);
// No change to status code based on endpoints
Mockito.when(status.getStatusCode()).thenReturn(withResponseCode);
Mockito.when(httpResponse.getStatusLine()).thenReturn(status);
HttpEntity entity = Mockito.mock(HttpEntity.class);
Object[] args = invocation.getArguments();
String endpoint = ((HttpPost) args[0]).getURI().getPath();
if (endpoint.contains("/a/b")) {
entity = EntityBuilder.create().setText("something").build();
Mockito.when(httpResponse.getEntity()).thenReturn(entity);
} else {
entity = EntityBuilder.create().setText("something else").build();
Mockito.when(httpResponse.getEntity()).thenReturn(entity);
}
return httpResponse;
}
}).when(client).execute(Mockito.any(HttpUriRequest.class));
集成测试不会测试其余客户端本身,我不需要旋钮和多个模拟客户端来进行不同的响应。以上内容帮助我根据接收请求的端点返回不同的响应。