Silne typowanie w asercji jsonPath()

Silne typowanie w asercji jsonPath()
NO
  • Rejestracja:ponad 2 lata
  • Ostatnio:12 dni
  • Postów:135
0

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

Kopiuj
@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:

Kopiuj
{
  "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.

edytowany 2x, ostatnio: Riddle
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 9 godzin
  • Postów:1880
1

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


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
NO
  • Rejestracja:ponad 2 lata
  • Ostatnio:12 dni
  • Postów:135
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

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:minuta
  • Lokalizacja:Koszalin
  • Postów:10094
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".

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 14 godzin
  • Postów:2370
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).

edytowany 1x, ostatnio: yarel
Skoq
  • Rejestracja:około 6 lat
  • Ostatnio:3 dni
  • Lokalizacja:Kraków
  • Postów:255
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


I tak to właśnie jest
W0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 8 godzin
  • Postów:3603
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.

99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:6 miesięcy
  • Postów:2420
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.


Holy sh*t, with every month serenityos.org gets better & better...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.