• November 5, 2024
API tests using Apache HTTP Client

Apache HTTP Client is a library that allows us to write HTTP requests. Not only that we can use all the available HTTP methods, but the HTTP Client library can also be used for SSL requests as well as user authentication methods and proxies. In this blog post, you will see how you can create HTTP requests using this library and we will execute each method against the web service. Now let’s try to create GET, POST, PUT and DELETE operations for the below dummy Web Service API example:

http://dummy.restapiexample.com/public

Create simple API tests using Apache HTTP Client

Let’s assume that you already have the Maven project setup and one of the JUnit or TestNG runner are configured. Couple of things you need to add as dependencies in your pom.xml:

Once you have everything setup in place, we can start creating the HTTP methods.

API tests using Apache HTTP Client
HTTP Methods

GET Request

Create a class and on top of it add this:

HttpClient httpClient = HttpClients.custom().build();

This will be used to actually execute all the HTTP requests later on.

Then we create the method shown below:

protected HttpResponse httpGet(String endpoint) throws Exception {
    HttpGet request = new HttpGet(endpoint);
    HttpResponse response = httpClient.execute(request);
    getResponseEntity(response);
    return response;
}

The method needs to return HTTPResponse type since we want to do assertions after the call. HTTP Response is the message that is returned from the server to the client. This method accepts a string, which is the endpoint as an argument. Then we create an instance of HttpGet class where we provide the endpoint which will be passed as an argument to the method. The execute() method as part of the HttpClient interface returns HTTPResponse so we are storing the execution response in a variable called the response of HTTPResponse type.

private void getResponseEntity(HttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();
String body = EntityUtils.toString(response.getEntity());
HttpEntity newEntity = new StringEntity(body, ContentType.get(entity));
response.setEntity(newEntity);
}

The method called getResponseEntity(response) does couple of things:

  • Accepts HTTPResponse as an argument
  • Creates an HTTPEntity that calls the getEntity() method from the interface. This fetches the message from the response
  • Creates a string variable that stores the converted response to a string
  • Creates new StringEntity which accepts the already “converted-to-string entity” and the content-type entity provided
  • In the last line, we set the newly stored string entity

The GET method returns the response of HTTPResponse type. Since we’ve created the request, let’s see how we can effectively utilize it in a test.

First, we create the client called getAllEmployees() which calls the httpGet method that we already created.

public HttpResponse getAllEmployees() throws Exception {
return httpGet(GET_EMPLOYEES);
}

Then, in the test, we call that method and store the result in a response variable of HTTPResponse type in order to get the status code and assert it (for the purpose of explaining how we can create HTTP methods, I’m only going to show a status code assertion).

@Test
public void shouldGetAllEmployees() throws Exception {
    HttpResponse response = clients.getAllEmployees();
    log.info("Create request: " + response);

    int statusCode = response.getStatusLine().getStatusCode();
    assertThat(statusCode, is(equalTo(SC_OK)));
}

POST Request

The concept is similar to the httpGet method but this time we are passing an additional argument which is the JSON payload itself.

First, we instantiate the HttpPost class. Then we’re setting the entity which accepts the JSON payload and we’re just executing it in the same manner and return the response.

protected HttpResponse httpPost(String endpoint, String jsonPayload) throws IOException {
    HttpPost request = new HttpPost(endpoint);
    request.setEntity(new StringEntity(jsonPayload));
    HttpResponse response = httpClient.execute(request);
    getResponseEntity(response);
    return response;
}

We create the client:

public HttpResponse createEmployee(String payload) throws Exception {
return httpPost(CREATE_EMPLOYEE, payload);
}

To use all of this in a test it would look like:

@Test
public void shouldCreateEmployee() throws Exception {
    private PostEmployeeRequestModel postEmployeeRequestModel =        PostEmployeeRequestModel.builder()
        .name("Vladimir")
        .salary("200000")
        .age("27")
        .build();

    String createEmployeeRequestBody = objectToString(postEmployeeRequestModel);
    
    HttpResponse actualResponse = clients.createEmployee(createEmployeeRequestBody);

    assertThat(actualResponse.getStatusLine().getStatusCode(), is(equalTo(SC_OK)));
}

Creating the request payload using the @Builder Lombok feature annotation, then serializing it as a string and storing it in a variable. That variable is passed as an argument to the createEmployee() client. The response is extracted and the status code is checked.

PUT Request

Basically, the concept of the PUT request is the same as the POST request in our example. The difference is:

  • We use HttpPut class
  • Different endpoint

Even though the payload is the same as the POST request payload, this request updates everything related to the employee. As a path parameter, we are passing the id of the employee. We construct the payload and change the method to PUT since it will not create a new resource, rather it will update the existing one.

protected HttpResponse httpPut(String endpoint, String jsonPayload) throws IOException {
    HttpPut request = new HttpPut(endpoint);
    request.setEntity(new StringEntity(jsonPayload));
    HttpResponse response = httpClient.execute(request);
    getResponseEntity(response);
    return response;
}

The client and the test would be straightforward to create:

public HttpResponse updateEmployee(String payload, int employee) throws Exception {
return httpPut(UPDATE_EMPLOYEE + employee, payload);
}
@Test
public void shouldUpdateEmployee() throws Exception {
String updateEmployeeModel = objectToString(postEmployeeUpdateModel);

HttpResponse actualResponse = clients.updateEmployee(updateEmployeeModel, 1);

assertThat(actualResponse.getStatusLine().getStatusCode(), is(equalTo(SC_OK)));
}

DELETE Request

The DELETE request should be easy to create and understand. Below are the request, client and test.

protected HttpResponse httpDelete(String endpoint) throws IOException {
    HttpDelete request = new HttpDelete(endpoint);
    HttpResponse response = httpClient.execute(request);
    getResponseEntity(response);
    return response;
}
public HttpResponse deleteEmployee(String employee) throws Exception {
    return httpDelete(DELETE_EMPLOYEE + employee);
}
@Test
public void shouldDeleteEmployee() throws Exception {
HttpResponse actualResponse = clients.deleteEmployee(1);
assertThat(actualResponse.getStatusLine().getStatusCode(), is(equalTo(SC_OK)));
}

The client deleteEmployee(1) is deleting the employee with id: 1 which we pass as an argument. The regular status code assertion is checked as a validation.

That’s a wrap folks! This is how you create a simple API tests using Apache HTTP Client library.

Share This Post


Latest Posts