简体   繁体   中英

How to mock HttpClient class to return different responses

How can I make Mockito return different HttpEntity values in response to different URIs?

The test is going to make multiple HTTP requests (all of them are POST requests) with the mockHttpClient.

HttpEntity httpEntity = EntityBuilder.create().setText(response).build();
PowerMockito.when(response, "getEntity").thenReturn(httpEntity);

And the test itself is designed this way:

CloseableHttpClient client = mockHttpClient(200, HTTP_ENTITY);
runTest();
Mockito.verify(client, Mockito.times(2)).execute(Mockito.any());

For the above test to return different HTTP entities, I tried the following:

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);

But I'm unable to build different http entities and get in response based on the URIs in the request.

First things first, there is no need for Powermock in this case. You do not need to mock static methods, constructors or anything else nasty.

I've prepared a little example test, which works out of the box for me here with Mockito 2.23.4 , and you can see that the assertion isSameAs ("Verifies that the actual value is the same as the given one, ie using == comparison.") really checks if a certain POST call matches the previously mocked response:

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);
    }
}

Thank you mle. Your response helped me understand how to better structure a test. But in this case I'm trying to modify one without any restructuring.

I thought I ll post my answer here just in case someone else is looking for one.

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)); 

The integration test does is not testing the rest client itself and I don't need knobs and multiple mock clients for different responses. And the above helps me in returning different responses based on the endpoint that is receiving requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM