如何使用Mockito模拟HttpClient [英] How to mock HttpClient using Mockito

查看:747
本文介绍了如何使用Mockito模拟HttpClient的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我正在写junit的我的实际课程.我将HtpClient设置为私有和最终版本.

This is my Actual class for which i am writing junit. I have HtpClient as private and final.

 public class KMSHttpClientImpl implements KMSHttpClient
 {
/**
 * ObjectMapper Instance.
 */
private final ObjectMapper objectMapper = new ObjectMapper ();

/**
 * KMS ConnectionManager Instance.
 */
private final KMSHttpConnectionManager kmsHttpConnectionManager =
        new KMSHttpConnectionManagerImpl ();

/**
 * HttpClient object.
 */

private final HttpClient httpClient;

/**
 * KMSHttpClient constructor.
 */
public KMSHttpClientImpl ()
{
    // TODO PoolingHttpClientConnectionManager object should be closed after use.
    // TODO This needs to be either singleton or should be kept in static block
    final PoolingHttpClientConnectionManager connectionManager =
            kmsHttpConnectionManager.getConnectionManager();
    httpClient = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();
}

@Override
public <T> T invokeGETRequest (final String url, final Class<T> clazz)
        throws KMSClientException
{
    final HttpGet httpGet = new HttpGet(url);
    try {
        final HttpResponse response = httpClient.execute(httpGet);
        return objectMapper.readValue(
                response.getEntity().getContent(), clazz);
    } catch (IOException e) {
        throw new KMSClientException("Unable to get the result", e);
    }
}

@Override
public <T> T invokePOSTRequest (final String url, final Object object, final Class<T> clazz)
        throws KMSClientException
{
    final HttpPost httpPost = new HttpPost(url);
    try {
        final HttpResponse response = httpClient.execute(httpPost);
        return objectMapper.readValue(
                response.getEntity().getContent(), clazz);
    } catch (IOException e) {
        throw new KMSClientException("Unable to create the request", e);
    }
}
 }

这是我的测试课.我正在尝试模拟HttpClient,但由于最终我无法模拟它.如果我从KMSHttpClientImpl.java类的HttpClient中删除final.我收到PMd问题说 专用字段"httpClient"可以设为最终值;它仅在声明或构造函数中初始化.我该怎么做才能解决此问题?

This is my testclass. I am trying to Mock HttpClient but as it is final i cant mock it. And if i remove final from HttpClient in my KMSHttpClientImpl.java class. I am getting PMd issue saying Private field 'httpClient' could be made final; it is only initialized in the declaration or constructor. What can i do to fix this issue?

public class KMSHttpClientImplTest
{

/**
 * Injecting mocks KMSHttpClientImpl.
 */
@InjectMocks
private KMSHttpClientImpl kmsHttpClientImpl;

/**
 * Mock HttpClient.
 */
@Mock
private HttpClient httpClient;


/**
 * Initial SetUp Method.
 */
@Before
public void setUp ()
{
    initMocks(this);
}

/**
 * Method to test postRequest Method.
 * @throws KMSClientException
 */
@Test
public void testPostRequest () throws KMSClientException
{
    final OrganizationRequest request = getOrganizationRequest();
    final HttpResponse response = prepareResponse(HttpStatus.SC_OK);
    try {
        Mockito.when(httpClient.execute(Mockito.any())).thenReturn(response);
        final OrganizationResponse organizationResponse = kmsHttpClientImpl.invokePOSTRequest(
                ORG_TEST_URL, request, OrganizationResponse.class);
        assertEquals("Id should match", ORG_ID, organizationResponse.getId());
    } catch (IOException e) {
        throw new KMSClientException("Unable to create the request", e);
    }
      }

/**
 * Method to test getRequest Method.
 * @throws KMSClientException
 */
@Test
public void testGetRequest () throws KMSClientException
{
    try {
        final HttpResponse response = prepareResponse(HttpStatus.SC_OK);
        Mockito.when(httpClient.execute(Mockito.any())).thenReturn(response);
        final OrganizationResponse organizationResponse = kmsHttpClientImpl.invokeGETRequest
                (ORG_TEST_URL, OrganizationResponse.class);
        assertEquals("Id should match", ORG_ID, organizationResponse.getId());
    }  catch (IOException e) {
        throw new KMSClientException("Unable to create the request", e);
    }
}

/**
 * Method to organizationRequest Object.
 * @return OrganizationRequest object
 */
public OrganizationRequest getOrganizationRequest ()
{
    return OrganizationRequest.builder().id("test").build();
}

/**
 * Method to getOrganizationResponse String.
 * @return String Object
 */
public String getOrganizationResponse ()
{
    final Map obj=new HashMap();
    obj.put("id", ORG_ID);
    obj.put("uuid", ORG_UUID);
    obj.put("orgKeyId", ORG_KEYID);
    return JSONValue.toJSONString(obj);
}

/**
 * Method to prepare Response.
 * @param expectedResponseStatus
 * @return HttpResponse
 */
private HttpResponse prepareResponse (final int expectedResponseStatus)
{
    final HttpResponse response = new BasicHttpResponse(new BasicStatusLine(
            new ProtocolVersion("HTTP", 1, 1),
            expectedResponseStatus, ""));
    response.setStatusCode(expectedResponseStatus);
    final HttpEntity httpEntity = new StringEntity(getOrganizationResponse(),
            ContentType.APPLICATION_JSON);
    response.setEntity(httpEntity);
    return response;
     }
    }

推荐答案

测试HTTP客户端代码的一种方法是不模拟您的HTTPClient对象,而是为http调用创建模拟响应,然后让您的HPPTClient拨打这些网址. 看看Wiremock. http://wiremock.org/docs/ 它可以帮助您创建一个简单的模拟服务器,并且可以对URL的响应进行存根. 然后使用客户端进行测试来调用您的URL.

One of the ways to test a HTTP client code would be to not mock your HTTPClient object, but to create mock responses for the http calls and then let your HPPTClient make calls to those URLs. Take a look at Wiremock. http://wiremock.org/docs/ It helps you create a simple mock server and you can stub responses for your URLs. Then invoke your URLs using your client for the test.

这篇关于如何使用Mockito模拟HttpClient的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆