Cześć drogi czytelniku 🙂 ! Dzisiejszy artykuł przeznaczyłam na opisanie Mockito w testach jednostkowych. Skupiałam się tutaj na podstawowych funkcjonalnościach takich jak: Matchers, wyjątki i ArgumentCaptor.
1. Machers
Argument Matchers wykorzystywane są gdy chcemy przetestować metodę ale nie wiemy z jakim argumentem. I tak np. kontynuując przykład z wpisu: Weryfikacja wywołań metod na Mockach sprawdzenie czy metoda canHandleCart zostanie wywołana z parametrem cart:
given(cartHandler.canHandleCart(cart)).willReturn(true);
może zostać zapisana z wykorzystaniem matcher’a „any” który przejmuje każdą wartość. Wówczas zapis będzie wyglądał następująco:
given(cartHandler.canHandleCart(any())).willReturn(true);
Współpracując z tym Matcher’em metodę tą możemy zapisać również w następujący sposób:
given(cartHandler.canHandleCart(any(Cart.class))).willReturn(true);
– dzięki temu że matchers „any” sprecyzowaliśmy o wartość klasy Cart – any będzie precyzowało tylko argumenty klasy Cart.
Dobre praktyki jednak mówią iż jeżeli jest to tylko możliwe używać matchersów danego typu. Więc jeśli gdzieś jest wymagany int najlepiej zastosować anyInt(). Z matchersów możemy także korzystać z wykorzystaniem metody verify oraz then.should() np.:
verify(cartHandler, atLeastOnce()).sendToPrepare(any(Cart.class));
W sytuacji gdy metoda składa się z kilku parametrów to decydując się na wykorzystanie matchersów powinniśmy konsekwentnie w ten sposób zdefiniować każdy parametr.
Warto również wiedzieć że metoda given().willReturn() możne przyjmować kilka parametrów.:
given(cartHandler.canHandleCart(cart)).willReturn(true, false); //then assertThat(cartHandler.canHandleCart(cart), equalTo(true)); assertThat(cartHandler.canHandleCart(cart), equalTo(false));
Również w miejscu matchera możemy skorzystać z wyrażeń lambda w miejscu wartości lub matchera. Wykorzystujemy do tego metodę boolean argThat, która znajduje się w klasie ArgumentMatchers w bibliotece Mockito.
given(cartHandler.canHandleCart(argThat(c -> cart.getOrders().size > 0))).willReturn(true,false);
2. Wyjątki
Natomiast aby przetestować możliwość generowania wyjątków przez naszą metodę korzystając z metody testowej given() zamiast willReturn() korzystamy z willThrow(): i sprawdzamy asercją assertThrow.
given(cartHandler.canHandleCart(cart)).willThrow(IllegalStateException.class); assertThrow(IllegalStateException.class, () -> cartService.processCart(cart));
3. Argument Captor
ArgumentCaptor służy do sprawdzenia z jakimi argumentami została wywołana dana metoda.
ArgumentCaptor<określamy jakiego typu bedzie argument> argumentCaptor = ArgumentCaptor.forClass(Cart.class); Dla naszego przykładu Cart będzie to więc wyglądać następująco: ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Cart.class);
Przechwycenie argumentu dzieje się w momencie weryfikacji danej metody gdy korzystamy z then.Should() lub z metody verify.
then(cartHandler).should().sendToPrepare(argumentCaptor .capture()); verify(cartHandler).should().sendToPrepare(argumentCaptor .capture());
ArgumentCaptorem możemy sprawdzić np wielkość listy w obiekcie. Wykorzystujemy do tego metodę getValue() która dotyczy tylko jednego argumentu. Natomiast za pomocą metody getAllValues() pobieramy wszystkie argumenty danej listy.
assertThat(argumentCaptor.getValue().getOrders().size(), equalTo(1)); assertThat(argumentCaptor.getAllValues().size(),equalTo(2)); assetThat(argumentCaptor.getAllValues().get(0).getOrders().size(), equalTo(1);
4. Podsumowanie
Wykorzystanie biblioteki Mockito w testach jednostkowych daje nam spore możliwości w przeprowadzaniu testów. Na zakończenie zapraszam Cię drogi czytelniku do kolejnych artykułów na temat testów np: Weryfikacja wywołań metod na Mockach oraz do artykułu: „Piramida, diament i trofeum – jak rozplanować testy automatyczne w aplikacji” – Przemka Bykowskiego. Znajdziesz tam informacje na temat testów jednostkowych, integracyjnych oraz E2E 🙂 .
Czy jeśli w zamiast Captor użyłbym czegoś takiego:
then(cartHandler).should().sendToPrepare(cart);
to byłby to błąd?