Mocking Apache HTTPClient using Mockito

Viewed 94684

I'm trying to mock Apache HttpClient Interface in order to mock one of its methods mentioned below to return a stubbed JSON object in response.

HttpResponse response = defaultHttpClient.execute(postRequest); 

Could somebody be able to suggest how to achieve this with some sample code? Your help would be greatly appreciated.

Thanks

5 Answers

There is a nicer way to do this without having to add PowerMock as yet another dependency. Here you only need an extra constructor taking HTTPClient as an argument and Mockito. In this example I'm creating a custom health check (Spring Actuator) and I need to mock the HTTPClient for unit testing.

Libs: JUnit 5, Spring Boot 2.1.2 and Mockito 2.

Component:

@Component
public class MyHealthCheck extends AbstractHealthIndicator {

    HttpClient httpClient;

    public MyHealthCheck() { 
        httpClient = HttpClientBuilder.create().build();
    }

    /** 
    Added another constructor to the class with an HttpClient argument.
    This one can be used for testing
    */ 
    public MyHealthCheck(HttpClient httpClient) { 
        this.httpClient = httpClient; 
    }

    /**
    Method to test 
    */ 
    @Override
    protected void doHealthCheck(Builder builder) throws Exception {

        //
        // Execute request and get status code
        HttpGet request = new HttpGet("http://www.SomeAuthEndpoint.com");
        HttpResponse response = httpClient.execute(request);

        //
        // Update builder according to status code
        int statusCode = response.getStatusLine().getStatusCode();
        if(statusCode == 200 || statusCode == 401) {
            builder.up().withDetail("Code from service", statusCode);
        } else {
            builder.unknown().withDetail("Code from service", statusCode);
        }
    }
}

Test method:

Note that here we use Mockito.any(HttpGet.class)

private static HttpClient httpClient;
private static HttpResponse httpResponse;
private static StatusLine statusLine;

@BeforeAll
public static void init() {
    //
    // Given
    httpClient = Mockito.mock(HttpClient.class);
    httpResponse = Mockito.mock(HttpResponse.class);
    statusLine = Mockito.mock(StatusLine.class);
}


@Test
public void doHealthCheck_endReturns401_shouldReturnUp() throws Exception {

    //
    // When
    when(statusLine.getStatusCode()).thenReturn(401);
    when(httpResponse.getStatusLine()).thenReturn(statusLine);
    when(httpClient.execute(Mockito.any(HttpGet.class))).thenReturn(httpResponse);

    //
    // Then
    MyHealthCheck myHealthCheck = new MyHealthCheck(httpClient);
    Health.Builder builder = new Health.Builder();
    myHealthCheck.doHealthCheck(builder);
    Status status = builder.build().getStatus();
    Assertions.assertTrue(Status.UP == status);
}

You can look at HttpClientMock, I wrote it for internal project but later decided to open source. It allows you to define mock behavior with fluent API and later verify a number of made calls. Example:

HttpClientMock httpClientMock = new 
HttpClientMock("http://localhost:8080");
httpClientMock.onGet("/login?user=john").doReturnJSON("{permission:1}");

httpClientMock.verify().get("/login?user=john").called();
Related