Mocking Apache HTTPClient using Mockito

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

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

回答1:

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)



回答2:

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


回答3:

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


回答4:

You can do this easily using PowerMockito which can also mock final/static methods, private methods and anonymous classes easily. Here's the sample code for mocking http request. JSON_STRING_DATA is any string which you want to get from execute method.

PowerMockito.mockStatic(DefaultHttpClient.class);     HttpClient defaultHttpClientMocked =  PowerMockito.mock(DefaultHttpClient.class);             PowerMockito.when(defaultHttpClientMocked.execute(Mockito.any(HttpPost.class))).thenReturn(createMockedHTTPResponse(JSON_STRING_DATA));


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!