TestRestTemplate HTTP Post Example

This tutorial will teach you how to use TestRestTemplate to send HTTP Post requests.

If you are also interested to learn how to send an HTTP GET request, then please have a look at the “Get List of Objects with TestRestTemplate” tutorial.

What is TestRestTemplate?

TestRestTemplate is HTTP Client that you use for Spring Boot integration tests. And you will use TestRestTemplate in a very similar way you use RestTemplate HTTP Client. Although these two HTTP clients are very similar, TestRestTemplate does not extend the RestTemplate HTTP Client. The reason you will want to use TestRestTemplate for integration tests instead of regular RestTemplate is that TestRestTemplate offers a simplified approach to testing HTTP requests that require Basic Authentication.

Also, TestRestTemplate is fault tolerant. This means that 4xx and 5xx do not result in an exception being thrown and can instead be detected via the response entity object and its HTTP status code.

Maven Dependency

To be able to use TestRestTemplate in your Spring Boot project, you will need to have the following dependency in pom.xml file.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Inject TestRestTemplate into a Test Class

If you are using the @SpringBootTest annotation with an embedded server, you can inject the TestRestTemplate object into your test class with the @Autowired annotation.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UsersControllerIntegrationTest {

    @Autowired
    private TestRestTemplate testRestTemplate;

   ...

}

HTTP Post to Get Plain JSON

To send HTTP Post requests using TestRestTemplate object,  you can use postForObject() or postForEntity() methods.

If you use postForEntity() method, then in response back you will get the ResponseEntity object from which you can also get HTTP Status code, HTTP headers and response body.

ResponseEntity<String> createdUserDetailsEntity = testRestTemplate.postForEntity("/users", request, String.class); 
String jsonBody = createdUserDetailsEntity.getBody(); 

Example of a Test Method

Below is an example of a test method that will send an HTTP post request to a /users API endpoint. If the request is successful and a new user is created, in response back we will get ResponseEntity that contains the HTTP response status code, response body and HTTP headers that we can validate with assertions.

@Test
@DisplayName("User can be created")
void testCreateUser_whenValidDetailsProvided_returnsUserDetails() throws Exception {

    // Arrange
    JSONObject userDetailsRequestJson = new JSONObject();
    userDetailsRequestJson.put("firstName","Sergey");
    userDetailsRequestJson.put("lastName","Kargopolov");
    userDetailsRequestJson.put("email","[email protected]");
    userDetailsRequestJson.put("password","12345678");
    userDetailsRequestJson.put("repeatPassword","12345678");

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

    HttpEntity<String> request =
            new HttpEntity<String>(userDetailsRequestJson.toString(), headers);


    // Act
    ResponseEntity<String> createdUserDetailsEntity = testRestTemplate.postForEntity("/users", request, String.class);
    String jsonBody = createdUserDetailsEntity.getBody();
    JsonNode createUserResponseJson = new ObjectMapper().readTree(jsonBody);


    // Assert
    assertEquals(HttpStatus.OK, createdUserDetailsEntity.getStatusCode());

    assertEquals(userDetailsRequestJson.get("firstName"),
            createUserResponseJson.path("firstName").asText(),
            "Returned user's first name seems to be incorrect");

    assertEquals(userDetailsRequestJson.get("lastName"),
            createUserResponseJson.path("lastName").asText(),
            "Returned user's last name seems to be incorrect");

    assertEquals(userDetailsRequestJson.get("email"),
            createUserResponseJson.path("email").asText(),
            "Returned user's email seems to be incorrect");

    assertFalse(createUserResponseJson.path("userId").asText().trim().isEmpty(),
            "userId should not be empty");

    assertTrue(createUserResponseJson.path("password").asText().trim().isEmpty(),
            "Password should NOT be returned");

    assertTrue(createUserResponseJson.path("repeatPassword").asText().trim().isEmpty(),
            "Repeat Password should NOT be returned");
}

HTTP Post for Java Object

Alternatively to using the postForEntity() method, you can use the postForObject() and get back the requested Java object right away.

Get Plain Object

UserRest createdUserDetails = restTemplate.postForObject("/users", request, UserRest.class);

Notice that in this case we no longer have access to the HTTP response status code or HTTP headers. To get this information we will need to use postForEntity() method instead.

Get Plain Object Wrapped into ResponseEntity

ResponseEntity<UserRest> createdUserDetails = restTemplate.postForEntity("/users", request, UserRest.class);
UserRest userDetails = createdUserDetailsEntity.getBody();

Example of a Test Method

Let’s look at an example of a test method that uses postForObject() method instead.

    @Test
    @Order(1)
    @DisplayName("User can be created")
    void testCreateUser_whenValidDetailsProvided_returnsUserDetails() throws Exception {

        // Arrange
 
        JSONObject userDetailsRequestJson = new JSONObject();
        userDetailsRequestJson.put("firstName","Sergey");
        userDetailsRequestJson.put("lastName","Kargopolov");
        userDetailsRequestJson.put("email","[email protected]");
        userDetailsRequestJson.put("password","12345678");
        userDetailsRequestJson.put("repeatPassword","12345678");

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

        HttpEntity<String> request =
                new HttpEntity<String>(userDetailsRequestJson.toString(), headers);

        // Act
        UserRest createdUserDetails =
                 restTemplate.postForObject("/users", request, UserRest.class);

        // Assert
        assertEquals(userDetailsRequestJson.get("firstName"),
                createdUserDetails.getFirstName(),
                "Returned user's first name seems to be incorrect");
        assertEquals(userDetailsRequestJson.get("lastName"),
                createdUserDetails.getLastName(),
                "Returned user's last name seems to be incorrect");
        assertEquals(userDetailsRequestJson.get("email"),
                createdUserDetails.getEmail(),
                "Returned user's email seems to be incorrect");

        assertFalse(createdUserDetails.getUserId().toString().trim().isEmpty(),
                "userId should not be empty");
}

Video lessons

I hope this tutorial was of some value to you. If you like video tutorials,  then have a look at my video course called “Testing Java with JUnit and Mockito“. This video course is for absolute beginners and you do not need to have any prior knowledge of testing Java applications to enrol.

Happy learning!