Zapisy otwarte! Dołącz do kursu Selenium w Javie lub Selenium w C#. Tylko do 23.09.2021 do godz. 21:00. Zapisz się tutaj.

API w REST Assured 13. Serializacja i deserializacja

Temat na dzisiaj to serializacja i deserializacja, czyli zamienianie odpowiedzi na obiekty w Javie i odwrotnie, „przepychanie” obiektów w Javie np. w metodzie POST.

Dokumentacja do sklepu

Po poprawnym postawieniu aplikacji dokumentację do niej znajdziesz pod localhost/fakestore/dokumentacja/. Tam też znajdziesz np. klucze potrzebne do uwierzytelnienia.

 

Serializacja i deserializacja

W tej lekcji zajmiemy się serializacją i deserializacją. Ale żeby to zrobić to fajnie byłoby zrozumieć najpierw te pojęcia. W wielkim skrócie: gdy odbieramy z API jakiś obiekt, jest on w JSONie, który jest niczym więcej niż tekstem w konkretnym formacie. Możemy (co już umiemy) parsować ten tekst przy pomocy jsonPath, możemy nawet tak sparsowane wartości podstawiać do zmiennych jedna po drugiej. Ale nie jest to ani szczególnie przyjemne, ani wydajne. Deserializacja, to bardziej zautomatyzowany proces przerabiania takiego response’a do obiektu javowego. Serializacja, to dokładna odwrotność tego procesu: zamieniamy obiekt javowy w JSONa (lub XMLa) dzięki czemu możemy go wysłać przez API. 

Klasa reprezentująca odpowiedź lub zapytanie

Jak to zrobić? Otóż najtrudniejsze, to stworzyć obiekt, który będzie w kodzie reprezentacją obiektu z API. Robimy to tworząc klasę, której pola powinny nazwami i typami odpowiadać tym z API. Możemy być pracowitym testerem i stworzyć klasę, która będzie miała wszystkie pola obiektu API, albo być rozsądnym testerem i zdefiniować tylko te, których naprawdę chcemy używać. Jednak, żeby nasza deserializacja nie rzucała później błędami musimy do takiej klasy dodać poniższą adnotację:

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Nasza klasa, to będzie takie POJO (Plain Old Java Object) składająca się z pól (które muszą mieć nazwy odpowiadające tym z API i zgodne typy) i prostych metod, które wygeneruje dla Was automatycznie IntelliJ. Ja wygenerowałem sobie gettery, settery, pusty i pełny konstruktor, oraz metodę toString, żeby móc chociaż zobaczyć, czy nasz obiekt się prawidłowo zdeserializował.

Teraz wszystko co musimy zrobić to powiedzieć RestAssured do jakiego obiektu chcemy podstawiać ten pobrany z API i jakiej klasy użyć jako wzorca deserializacji:

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Zwróć uwagę na ostatnią linijkę: .as(Product.class) mówi nam jako co mamy traktować taki obiekt.W drugą stronę jest w zasadzie jeszcze prościej. Mając stworzony obiekt klasy Product w kodzie po prostu przekazujemy go jako body naszego requesta… i tyle.

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Przypominam, żeby w naszym API przetestować coś więcej niż kod 201 po utworzeniu obiektu, bo pozwala ono na tworzenie obiektów nawet z nieprawidłowym (albo pustym) body. Dlatego upewniam się, że w responsie (w którym otrzymujemy cały utworzony obiekt) nazwa zgadza się z tą z obiektu javowego. 

Kod

Klasa SerialTest

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Product

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

POM: dodatkowa zależność

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Wsparcie merytoryczne

Nie masz dostępu do wsparcia merytorycznego dla tego kursu. Wykup dostęp albo zaloguj się, by móc zadawać pytania.

  1. Hej, mam takie pytanko
    Chciałbym zmodyfikować nieco konstruktor klasy Product w taki sposób, aby uwzględniał także nazwę kategorii produktu, w jakiej się dany produkt znajduje. Mam z tym problem, gdyż ta nazwa kategorii nie jest tak łatwo dostępna jak id czy name, ale znajduje się wewnątrz listy 'categories' w JSON-ie. A wiem, na podstawie tego co napisałeś powyżej, że pola klasy Product powinny nazwami i typami odpowiadać tym z API.
    Czy istnieje jakiś prostszy sposób na "dobranie się" do tej nazwy kategorii od stworzenia listy obiektów, która zwróciłaby nam podczas deserializacji wszystko co jest wewnątrz 'categories'?
    Jeśli nie, to w jaki sposób poprawnie przekazać taką przykładową listę przy tworzeniu instancji klasy Product (podczas serializacji)?
    Product product = new Product(0, "nazwa", "slug", "opis", ... );

    Odpowiedz