Silne typowanie w asercji jsonPath()

0

Mam taki test integracyjny, który sprawdza czy po rezerwacji miejsca ma ono odpowiedni status, widoczny w czasie przeglądania miejsc:

@Test
void should_seat_be_busy_after_booking() throws Exception {
    //given
    var seat = prepareSeat();
    var screening = seat.getScreening();

    //when
    mockMvc.perform(
            post("/bookings/")
                    .param("seatId", seat.getId().toString())
    );

    //then
    mockMvc.perform(
            get("/screenings/" + screening.getId() + "/seats")
    ).andExpect(
            jsonPath(
                    "$.content[?(@.id == '%s' && @.status == '%s')]",
                    seat.getId(),
                    SeatStatus.BUSY
            ).exists()
    );
}

Zwracany json:

{
  "content": [
    {
      "id": 1,
      "rowNumber": 1,
      "number": 1,
      "status": "FREE"
    },
    {
      "id": 2,
      "rowNumber": 1,
      "number": 2,
      "status": "FREE"
    },
    {
      "id": 3,
      "rowNumber": 1,
      "number": 3,
      "status": "FREE"
    },
    {
      "id": 4,
      "rowNumber": 1,
      "number": 4,
      "status": "FREE"
    },
    {
      "id": 5,
      "rowNumber": 1,
      "number": 5,
      "status": "FREE"
    }
  ],
  "pageable": {
    "sort": {
      "empty": true,
      "unsorted": true,
      "sorted": false
    },
    "offset": 0,
    "pageNumber": 0,
    "pageSize": 10,
    "paged": true,
    "unpaged": false
  },
  "last": false,
  "totalPages": 15,
  "totalElements": 150,
  "size": 10,
  "number": 0,
  "sort": {
    "empty": true,
    "unsorted": true,
    "sorted": false
  },
  "first": true,
  "numberOfElements": 10,
  "empty": false
}

Zamiast tego stringa: "$.content[?(@.id == '%s' && @.status == '%s')]" chciałbym użyć czegoś lepszego, bardziej type-safe. Kombinowałem z różnymi matcherami, ale za każdym razem coś jest nie tak. Chat GPT też jakoś nie potrafi znaleźć satysfakcjonującej odpowiedzi.

1

A nie możesz sobie tego zdeserializować choćby do HashMapy (albo DTO) i napisać asercje w Javie?

0
Charles_Ray napisał(a):

A nie możesz sobie tego zdeserializować choćby do HashMapy (albo DTO) i napisać asercje w Javie?

Teoretycznie mógłbym, ale nie wiem czy to by było takie proste. poza tym jestem ciekaw czy da się to zrobić tymi asercjami z jsonPath

0
Nofenak napisał(a):

Mam taki test integracyjny, który sprawdza czy po rezerwacji miejsca ma ono odpowiedni status, widoczny w czasie przeglądania miejsc:
Zamiast tego stringa: "$.content[?(@.id == '%s' && @.status == '%s')]" chciałbym użyć czegoś lepszego, bardziej type-safe. Kombinowałem z różnymi matcherami, ale za każdym razem coś jest nie tak. Chat GPT też jakoś nie potrafi znaleźć satysfakcjonującej odpowiedzi.

Nie jestem do końca przekonany czy type-safety w testach to jest coś co mogłoby Ci pomóc.

Weź pod uwagę, że jeśli nagle zaczniesz zwracać z API inny typ danych to testy nie powinny się wywalić błędem "nieudana serializacja", tylko czymś graceful w stylu "spodziewano się że pole x będzie y, a jest z".

1

@Nofenak: nie używałem, ale wygląda, że https://github.com/json-path/JsonPath#filter-predicates może być funkcjonalnością, o której piszesz (tj. zastąpienie stringly typed expression czymś silniejszym).

2
Nofenak napisał(a):
Charles_Ray napisał(a):

A nie możesz sobie tego zdeserializować choćby do HashMapy (albo DTO) i napisać asercje w Javie?

Teoretycznie mógłbym, ale nie wiem czy to by było takie proste. poza tym jestem ciekaw czy da się to zrobić tymi asercjami z jsonPath

To jest najprostsze rozwiązanie :D Dodatkowo patrząc pod kątem jakis przyszlych zmian tego response, o wiele latwiej bedzie zaktualizować asercję na obiekcie niz na jsonie xD

0

W pierwszej kolejności to sprawdź, czy JsonUnit nie ogarnia twojego problemu: https://github.com/lukas-krecan/JsonUnit
Jeśli są tam asercje, które cię zadowalają to po prostu użyj jakiegoś Gsona czy Jacksona do deserializacji do obiektu typu Json i jazda.

0

"$.content[?(@.id == '%s' && @.status == '%s')]" Co za bleeeeeeee.....

Ja zawszę radzę w takich przypadkach albo sobie wygenerować klienta OpenAPI (lub podobnego) i użyć w testach, lub zrobić deserializację do testowego DTO. Potem tego typu JPath ciężko przeczytać, zanalizować i zrozumieć, a jak się test wywali to i tak trzeba patrzeć w logi na cały request.

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