Assert Object Pattern – wyraź w testach biznesowe znaczenie obiektu

softwareskill.pl 3 lat temu

Assert Object pattern to bardzo prosty wzorzec który możesz zastosować w kodzie testowym sprawiając, iż będą prostsze i bardziej czytelne. Koncentruje się na fazie sprawdzania obiektów ukrywając złożoność sprawdzenia. Pokazuje znaczenie biznesowe jakie sprawdzamy.

Jako przykład weźmy klasę Basket reprezentującą koszyk zakupowy. Po dodaniu do koszyka produktu chcemy sprawdzić, czy znajduje się on w koszyku, ilość produktów jest równa 1, a cena za produkty wynosi dokładnie cenę tego produktu:

@Test @DisplayName("Inserts single product into empty basket") void insertsSingleProductIntoEmptyBasket() { // given var basket = make(an(EmptyBasket)); var product = make(a(BasicProduct)); // when basket.insert(product); // then assertThat(basket.getInsertedProducts().size()).isEqualTo(1); assertThat(basket.getInsertedProducts()).containsExactly(product); assertThat(basket.getItemsTotalPrice()).isEqualTo(product.getPrice()); }

W fazie sprawdzenia (assert) w testach częstym problemem jest zbytnie skupianie się na technicznych aspektach. Powoduje to dwie konsekwencje:

  • fazy assert są długie i mało czytelne,
  • skupiają się na technikaliach zamiast wyrażać wartość biznesową.

Kod koncentruje się na wewnętrznym modelu. I dobrze, bo ma go przetestować. Natomiast o ile istnieje więcej testów, te asercje trzeba by było kopiować. o ile dodanie produktu do koszyka tworzyłoby jeszcze jakiś dodatkowy efekt – wtedy należałoby zmodyfikować wszystkie testy.

Możesz zastosować prostą refaktoryzację wynosząc te sprawdzenia do osobnej metody w teście, albo zastosować Assert Object Pattern.

Assert Object Pattern

Ideą wzorca Assert Object jest „owinięcie” testowanego obiektu w obiekt Assert i stworzenie metod sprawdzających. W naszym przypadku będziemy testować obiekt Basket, więc utworzę BasketAssert:

@RequiredArgsConstructor(staticName = "assertThatBasket") public class BasketAssert { private final Basket basket; public BasketAssert isEmpty() { assertThat(basket.getInsertedProducts()) .isEmpty(); return this; } public BasketAssert holdsProducts(Product... products) { assertThat(basket.getInsertedProducts()) .containsOnly(products) .hasSize(products.length); assertThat(basket.getItemsTotalPrice()) .isEqualTo(Stream.of(products) .map(Product::getPrice) .reduce(BigDecimal.ZERO, BigDecimal::add)); return this; } }

Wtedy użycie w teście wygląda tak:

@Test @DisplayName("Inserts single product into empty basket") void insertsSingleProductIntoEmptyBasket() { // given var basket = make(an(EmptyBasket)); var product = make(a(BasicProduct)); // when basket.insert(product); // then assertThatBasket(basket).holdsProducts(product); }

Faza assert skróciła się i sprawdza biznesowe znaczenie, zamiast technikalia, sprawdzając je pole po polu.

Dla bardziej złożonych obiektów, kiedy wiele pól reprezentuje jakiś spójny stan, dzięki Assert Object Pattern możesz sprawdzić je wszystkie. Kiedy testujesz logikę tworzącą takie obiekty (lub operujące na nich), możesz w łatwy sposób sprawdzić czy wszystkie pola się zgadzają.

Dodatkową korzyścią jest to, iż w przypadku refaktoryzacji, możesz dołożyć kolejne pole do sprawdzenia, lub usunąć istniejące.

Inne uproszczenia fazy Assert

Innymi uproszczeniami w fazie assert może być:

  • Podczas różnego rodzaju konwersji, porównanie obiektu nie pole-po-polu, ale jako całość korzystając z wzorcowego obiektu stworzonego przez Test Data Builder (czytaj więcej).
  • W przypadku testów komponentowych, interakcji na mockach, można skorzystać z nazwanych klas Steps, które ukrywają złożoność procesową i sprawdzanie konkretnych argumentów (czytaj więcej).

Podsumowanie

Czym jest Assert Object Pattern

Ideą wzorca Assert Object jest „owinięcie” testowanego obiektu w obiekt Assert i stworzenie metod sprawdzających. Metody sprawdzające mogą mieć biznesowe znaczenie i sprawdzać wiele pól określając, czy obiekt jest spójny.

Jakie korzyści daje stosowanie Assert Object Pattern?

Faza sprawdzenia w teście mocno się upraszcza. Można wyrazić biznesowe znaczenie, zamiast koncentrować się nad technikaliami. Wprowadza uwspólnienie kodu pomiędzy testami.

Podoba Ci się ten artykuł? Weź więcej.

Jeżeli uważasz ten materiał za wartościowy i chcesz więcej treści tego typu – nie przegap ich i otrzymuj je prosto na swoją skrzynkę. Nawiążmy kontakt.

Dołączam

Dziękujemy!

Wysłaliśmy Ci mail powitalny, w którym znajdziesz link do aktywacji newslettera. Do usłyszenia!

Gdybyś potrzebował jeszcze więcej:

Jesteś Java Developerem?

Przejdź na wyższy poziom wiedzy
„Droga do Seniora” 🔥💪

Chcę więcej wiedzy

Jesteś Team Leaderem? Masz zespół?

Podnieś efektywność i wiedzę swojego zespołu 👌

Sprawdź

Wpis który czytasz to zaledwie fragment wiedzy zawartej w Programie szkoleniowym Java Developera od SoftwareSkill. Mamy do przekazania sporo usystematyzowanej wiedzy z zakresu kluczowych kompetencji i umiejętności Java Developera. Program składa się z kilku modułów w cotygodniowych dawkach wiedzy w formie video.

Chcę więcej wiedzy

Gdybyś potrzebował jeszcze więcej:

Jesteś Java Developerem?

Przejdź na wyższy poziom wiedzy
„Droga do Seniora” 🔥💪

Chcę więcej wiedzy

Jesteś Team Leaderem? Masz zespół?

Podnieś efektywność i wiedzę swojego zespołu 👌

Sprawdź
Idź do oryginalnego materiału