2014/05/12

Testing REST Service in Spring Boot with RestTemplate

I have decided to add my bit to Spring Boot's well-deserved popularity -- one must appreciate how fast you can create a simple application without compromising the design.

Of course, if you take your work seriously there is no way you can get by without  tests. An example is better than hours of explaining -- below you see testing of real service (no mocks) running locally:
  • in first case sending POST request to create a new record and creating an object to from the response
  • in second case GET request is send and the failure message is treaded as "raw" JSON


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Collections;

import static org.hamcrest.Matchers.*;
import static org.springframework.test.util.MatcherAssertionErrors.assertThat;


@RunWith (SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration (classes = Config.class)
@WebAppConfiguration
@IntegrationTest
public class UserControllerTest
{
  final String BASE_URL = "http://localhost:9999/customer/";

  @Test
  public void shouldCreateNewUser() {

    final String USER_NAME = "Leif Ericson";
    final String USER_ADDRESS = "Vinland";

    User user = new User();
    user.setName(USER_NAME);
    user.setAddress(USER_ADDRESS);

    RestTemplate rest = new TestRestTemplate();

    ResponseEntity<User> response = 
       rest.postForEntity(BASE_URL, user, User.class, Collections.EMPTY_MAP);
    assertThat( response.getStatusCode() , equalTo(HttpStatus.CREATED));

    User userCreated = response.getBody();
    assertThat( userCreated.getId() , notNullValue() );
    assertThat( userCreated.getName() , equalTo(CUSTOMER_NAME) );
    assertThat( userCreated.getAddress() , equalTo(CUSTOMER_ADDRESS) );
  }

  @Test
  public void shouldFailToGetUnknownUser()
  throws IOException {

    final int UNKNOWN_ID = Integer.MAX_VALUE;
    final String EXPECTED_ANSWER_MESSAGE = "user with id : '" + UNKNOWN_ID+ "' does not exist";

    RestTemplate rest = new TestRestTemplate();

    ResponseEntity<String> response = rest.getForEntity(BASE_URL + UNKNOWN_ID, String.class);

    assertThat( response.getStatusCode() , equalTo(HttpStatus.NOT_FOUND));

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode responseJson = objectMapper.readTree(response.getBody());
    JsonNode messageJson = responseJson.path("message");

    assertThat( messageJson.isMissingNode() , is(false) );
    assertThat( messageJson.asText() , equalTo(EXPECTED_ANSWER_MESSAGE) );
  }
}