mardi 30 juin 2020

How to integration test a RESTful APIs PUT endpoint with TestRestTemplate?

I'm currently working on a Spring Boot CRUD RESTful API with an User entity that consists of two parameters : name and id. Its endpoints are :

  • POST REQUEST IN /users - Create an user
  • GET REQUEST IN /users/{id} - List a specific user by its id
  • GET REQUEST IN /users - List all users
  • PUT REQUEST IN /users/{id} - Update a specific user by its id
  • DELETE REQUEST IN /users/{id} - Delete a specific user by its id

Each endpoint is built with a controller and a service to implement its logic.

I've already wrote unit tests for my controllers and services, now i'm trying to build integration tests to assert that my endpoints work properly as a group of components.

No mocking involved, all this will be done by using the TestRestTemplate and asserting that every operation was executed correctly and every response checked with its expected value.

The following are the tests I've already built :

@SpringBootTest(classes = UsersApiApplication.class,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest {

    @LocalServerPort
    private int port;

    TestRestTemplate restTemplate = new TestRestTemplate();
    HttpHeaders headers = new HttpHeaders();

    private void instantiateNewUser() {
        User userNumberFour = new User();
        userNumberFour.setName("Four");
        userNumberFour.setId(4L);

        ResponseEntity<User> responseEntity = restTemplate
                .postForEntity(createURLWithPort("/users"), userNumberFour, User.class);
    }

    @Test
    public void createNewUserTest() {
        User testUser = new User();
        testUser.setName("Test User");
        testUser.setId(5L);

        ResponseEntity<User> responseEntity = restTemplate
                .postForEntity(createURLWithPort("/users"), testUser, User.class);

        assertEquals(201, responseEntity.getStatusCodeValue());
        assertEquals(responseEntity.getBody(), testUser);
    }


    @Test
    public void listSpecificUserTest() throws JSONException {

        instantiateNewUser();
        HttpEntity<String> httpEntity = new HttpEntity<String>(null, headers);

        ResponseEntity<String> responseEntity = restTemplate.exchange(
                createURLWithPort("/users/4/"),
                HttpMethod.GET, httpEntity, String.class);

        String expectedResponseBody = "{id:4,name:Four}";

        assertEquals(200, responseEntity.getStatusCodeValue());
        JSONAssert.assertEquals(expectedResponseBody, responseEntity.getBody(), false);
    }

    @Test
    public void listAllUsersTest() throws JSONException {

        instantiateNewUser();
        HttpEntity<String> httpEntity = new HttpEntity<String>(null, headers);

        ResponseEntity<String> responseEntity = restTemplate.exchange(
                createURLWithPort("/users"),
                HttpMethod.GET, httpEntity, String.class);

        //All instantiated users
        ArrayList<String> expectedResponseBody = new ArrayList<>(Collections.emptyList());
        expectedResponseBody.add("{id:1,name:Neo}");
        expectedResponseBody.add("{id:2,name:Owt}");
        expectedResponseBody.add("{id:3,name:Three}");
        expectedResponseBody.add("{id:4,name:Four}");

        assertEquals(200, responseEntity.getStatusCodeValue());
        JSONAssert.assertEquals(String.valueOf(expectedResponseBody), responseEntity.getBody(), false);
    }

    @Test
    public void deleteSpecificUserTest() throws JSONException {

        instantiateNewUser();
        HttpEntity<String> httpEntity = new HttpEntity<String>(null, headers);

        ResponseEntity<String> responseEntity = restTemplate.exchange(
                createURLWithPort("/users/4/"),
                HttpMethod.DELETE, httpEntity, String.class);

        assertEquals(204, responseEntity.getStatusCodeValue());
        JSONAssert.assertEquals(null, responseEntity.getBody(), false);
    }

    private String createURLWithPort(String uri) {
        return "http://localhost:" + port + uri;
    }
}

As you can see, it's missing the PUT request method test, which is the update endpoint. To implement its logic, i need to send a message body with the content that will override the old users characteristics, but how?

This is what i made so far :

    @Test
    public void updateSpecificUserTest() throws JSONException {
    
        instantiateNewUser();
        HttpEntity<String> httpEntity = new HttpEntity<String>(null, headers);
    
        ResponseEntity<String> responseEntity = restTemplate.exchange(
                createURLWithPort("/users/4/"),
                HttpMethod.PUT, httpEntity, String.class);

        String expectedResponseBody = "{id:4,name:Four Updated}";
    
        assertEquals(200, responseEntity.getStatusCodeValue());
        JSONAssert.assertEquals(expectedResponseBody, responseEntity.getBody(), false);
    }
    

Would appreciate if someone could help with this one, didn't found the answer online.

Aucun commentaire:

Enregistrer un commentaire