Test integracyjny controllera

0

Stworzyłem test integracyjny dla takiego kontrolera:

@RestController
@RequestMapping("/")
public class MyController {

    @GetMapping(value = {"/get_all_clients/{page}"})
    public ResponseEntity<PageImpl<ClientsDto>> getAllClients(@PathVariable(value = "page") int page) {
	return new ResponseEntity<>(Mapper.toMode(clientsService.getAllClients(page),page), HttpStatus.OK);
   }
}

Przykładowy response dla /get_all_clients/0 wygląda tak:

{
  "content": [
    {
    "id": 0,
    "name": "Jan",
    "surname": "Kowalski",
    "age": 21
    }
  ],
  "number": 0,
  "size": 40,
  "totalElements": 1,
  "pageable": {
    "sort": {
      "sorted": true,
      "unsorted": false,
      "empty": false
    },
    "pageNumber": 0,
    "pageSize": 40,
    "offset": 0,
    "unpaged": false,
    "paged": true
  },
  "last": true,
  "totalPages": 1,
  "sort": {
    "sorted": true,
    "unsorted": false,
    "empty": false
  },
  "first": true,
  "numberOfElements": 1,
  "empty": false
}

W teście w dockerze uruchamiana jest baza danych, jest strzał do kontrolera i na końcu chciałbym porównać to co zwraca kontroler z tym co mam zapisane, czyli mam tak:

MvcResult result = this.mocMvc.perform(
                get("/get_all_clients/0")
                        .header("Content-Type", "application/json")
        )
        .andDo(print())
        .andExpect(status().isOk())
        .andReturn();

assertEquals(responseExpected, result.getResponse().getContentAsString());

problem polega na tym, że PageImpl zwracany z kontrolera nie zawsze wygląda tak samo, zmienia się kolejność pól.
Czasem jest tak:

"number": 0,
"size": 40,
"totalElements": 1,

innym razem:

"number": 0,
"totalElements": 1,
"size": 40,

Czy można nad tym jakoś zapanować? :)

4

Jasne, że się da.

  1. Napisać test tak, żeby nie porównywał stringów, ale zawartość JSONa. W twoim przypadku - zamiast serializować otrzymaną odpowiedź do Stringa lepiej zdeserializować responseExpected do PageImpl.

  2. Druga opcja to użyć ObjectMapper do odczytania JsonNode:

    ObjectMapper o = new ObjectMapper();
    assertEquals(o.readTree(expectedResponse), o.readTree(result.getResponse().getContentAsString()));
    
  3. Albo zagwarantować kolejność pól. Zgaduję, że używasz Jacksona, więc jest jacksonowe @JsonPropertyOrder : https://fasterxml.github.io/jackson-annotations/javadoc/2.7/com/fasterxml/jackson/annotation/JsonPropertyOrder.html

Opcja nr. 3 jest trochę słaba, bo przecież nie zależy ci na tym, by JSONy były zgodne co do formy, ale treści.

0

Wybrałem opcję numer 2. Działa! Dzięki ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1