Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking Apache HTTPClient using Mockito

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

like image 510
Global Dictator Avatar asked Dec 12 '13 11:12

Global Dictator


2 Answers

Here is what I did to test my code using Mockito and Apache HttpBuilder:

Class under test:

import java.io.BufferedReader; import java.io.IOException;  import javax.ws.rs.core.Response.Status;  import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClientBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory;  public class StatusApiClient { private static final Logger LOG = LoggerFactory.getLogger(StatusApiClient.class);      private String targetUrl = "";     private HttpClient client = null;     HttpGet httpGet = null;      public StatusApiClient(HttpClient client, HttpGet httpGet) {         this.client = client;         this.httpGet = httpGet;     }      public StatusApiClient(String targetUrl) {         this.targetUrl = targetUrl;         this.client = HttpClientBuilder.create().build();         this.httpGet = new HttpGet(targetUrl);     }      public boolean getStatus() {         BufferedReader rd = null;         boolean status = false;         try{             LOG.debug("Requesting status: " + targetUrl);               HttpResponse response = client.execute(httpGet);              if(response.getStatusLine().getStatusCode() == Status.OK.getStatusCode()) {                 LOG.debug("Is online.");                 status = true;             }          } catch(Exception e) {             LOG.error("Error getting the status", e);         } finally {             if (rd != null) {                 try{                     rd.close();                 } catch (IOException ioe) {                     LOG.error("Error while closing the Buffered Reader used for reading the status", ioe);                 }             }            }          return status;     } } 

Test:

import java.io.IOException;  import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.HttpHostConnectException; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito;  public class StatusApiClientTest extends Mockito {      @Test     public void should_return_true_if_the_status_api_works_properly() throws ClientProtocolException, IOException {         //given:         HttpClient httpClient = mock(HttpClient.class);         HttpGet httpGet = mock(HttpGet.class);         HttpResponse httpResponse = mock(HttpResponse.class);         StatusLine statusLine = mock(StatusLine.class);          //and:         when(statusLine.getStatusCode()).thenReturn(200);         when(httpResponse.getStatusLine()).thenReturn(statusLine);         when(httpClient.execute(httpGet)).thenReturn(httpResponse);          //and:         StatusApiClient client = new StatusApiClient(httpClient, httpGet);          //when:         boolean status = client.getStatus();          //then:         Assert.assertTrue(status);     }      @Test     public void should_return_false_if_status_api_do_not_respond() throws ClientProtocolException, IOException {         //given:         HttpClient httpClient = mock(HttpClient.class);         HttpGet httpGet = mock(HttpGet.class);         HttpResponse httpResponse = mock(HttpResponse.class);         StatusLine statusLine = mock(StatusLine.class);          //and:         when(httpClient.execute(httpGet)).thenThrow(HttpHostConnectException.class);          //and:         StatusApiClient client = new StatusApiClient(httpClient, httpGet);          //when:         boolean status = client.getStatus();          //then:         Assert.assertFalse(status);     }  } 

What do you think folks, do I need to improve something? (Yeah, I know, the comments. That is something I brought from my Spock background :D)

like image 170
user1855042 Avatar answered Sep 23 '22 21:09

user1855042


In your unit test class you need to mock defaultHttpClient:

@Mock
private HttpClient defaultHttpClient;

Then you tell mockito (for example in @Before method) to actually create your mocks by:

MockitoAnnotations.initMocks(YourTestClass);

Then in your test method you define what execute() method should return:

when(defaultHttpClient.execute(any()/* or wahtever you want here */)).thenReturn(stubbed JSON object);
like image 25
Flying Dumpling Avatar answered Sep 23 '22 21:09

Flying Dumpling