Jednostka testująca nieważną metodę

15

Aby naprawić błąd w aplikacji, zmodyfikowałem metodę o nazwie postLogin, dodając wywołanie do istniejącej metody o nazwie getShoppingCart.

Kod

protected void postLogin() {
  getShoppingCart();
}

Nie jestem jednak pewien, jaki jest najlepszy sposób na napisanie testu jednostkowego postLogin.

Podejście 1

Użyj weryfikacji z Mockito, aby po prostu sprawdzić, czy metoda została wywołana.

verify(mock).getShoppingCart();

Podejście 2

Przetestuj efekt uboczny wywołania metody, pobierając wartość koszyka na zakupy użytkownika.

AssertNotNull(user.getShoppingCart());

Czy jedno podejście jest lepsze od drugiego?

A_B
źródło
1
w zależności od tego, który test jest łatwiejszy do zrozumienia i utrzymuje kod w czystości. Jeśli nie masz pewności co do projektu testu, MUSI to być również znak, że projekt kodu jest wyłączony. Upewnij się, że padają pytania: „ Dlaczego nie dodając, że wywołanie metody naprawić błąd Czy to jest? PRAWO sposób, aby naprawić ten błąd?”
Caleb
8
O ile twoja getShoppingCart()metoda nie ma skutków ubocznych, nie musisz sprawdzać, jak się nazywa. Jeśli ma skutki uboczne, naprawdę powinieneś zmienić jego nazwę, ponieważ getXXX()metody konwencjonalnie powinny być idempotentne.
Jules
@Jules getNextValue? Prawdopodobnie ktoś mógłby powiedzieć „Nie nazywaj tego getterem; zmień nazwę na nextValue”, ale widziałem już wcześniej getNextużywane. Być może lepszym przykładem byłby obiekt reprezentujący elektron; co się stanie, kiedy zadzwonię getPosition? Lub gorzej,getPosition(); getVelocity();
Aaron

Odpowiedzi:

18

Zwykle wolałbym metodę 2.

Dlaczego? Ponieważ chcesz postLoginzmienić jakiś stan systemu, ale sposób, w jaki to osiąga (i jakie metody wywołuje w tym celu wewnętrznie), jest jedynie szczegółem implementacji, nic, na co Twój test jednostkowy powinien przyjąć jakiekolwiek założenia. Lepiej więc, aby twój test weryfikował tylko stan końcowy.

Doktor Brown
źródło
4

Zmieniłbym getShoppingCart na coś takiego jak initializeShoppingCart, cel tej metody powinien być jasny dla każdego, kto ją czyta, bez potrzeby sprawdzania, co robi metoda, a takie skutki uboczne mogą wywoływać zaskakujące zachowania dla użytkowników metody.

Jeśli getShoppingCart jest w innej klasie i jest już przetestowany jednostkowo, zastosowałbym podejście 1 - nie trzeba ponownie testować tego, co już przetestowano. W tym przypadku jesteśmy pewni, że getShoppingCart działa poprawnie i chcemy tylko upewnić się, że jest wywoływany z postLogin, więc jeśli ktoś w przyszłości usunie to wywołanie, test się nie powiedzie.

Jeśli getShoppingCart jest prywatną metodą, której nie można przetestować samodzielnie, zastosowałbym podejście 2, aby upewnić się, że po wywołaniu postLogin pożądana funkcjonalność getShoppingCart jest wykonywana zgodnie z oczekiwaniami.

Nastya S.
źródło
1

Podczas testowania wywołania funkcji (nieważne lub nie), które ma efekt uboczny, najbardziej kompletne jest sprawdzenie, czy efekt uboczny nie tylko występuje, ale również sprawdzenie, czy efekt uboczny (wyjście systemu lub zmiana stanu) jest pożądany.

hotpaw2
źródło
1
Chociaż jest to prawda, warto również wziąć pod uwagę, że szczegóły występującego efektu ubocznego mogą być częścią wewnętrznego stanu innego modułu i że sprawdzając te szczegóły, można połączyć test z nie tylko modułem, który jest to testowanie, ale także inny moduł, który może doprowadzić do kruchych testów, jeśli te szczegóły mogą ulec zmianie. Wyśmiewanie interfejsu między modułami pomaga zapobiec temu problemowi.
Jules
0

Nie będę omawiać twojego projektu, ale w twoim przypadku wybrałbym pierwsze podejście, ponieważ test jednostkowy służy do testowania, jakie metody robią technicznie niezależnie od ich pracy w domenie, to znaczy, co postLoginrobi twoja metoda ? Technicznie to wywołuje, getShoppingCardwięc musisz przetestować, który naprawdę dzwoni getShoppingCard, stworzę też kolejny test, getShoppingCardaby sprawdzić, co robi, a jeśli ma skutki uboczne, sprawdzę to w tym nowym teście.

La VloZ Merrill
źródło
0

Masz błąd w postLogin. Pierwszą rzeczą, którą powinieneś zrobić, to stworzyć test jednostkowy, który po wywołaniu postLogin bez oczekiwanego zestawu informacji „zawiedzie”.

Na podstawie powyższego pomysłu inną alternatywą spośród 2 proponowanych jest wstrzyknięcie informacji o koszyku jako parametru. Jeśli nie masz poprawnych informacji, zgłaszasz niesprawdzony wyjątek. Wyjaśni to, że bez prawidłowych danych twoja metoda jest skazana na niepowodzenie.

Będzie to wymagało niewielkiej zmiany, w której klient dzwoniący teraz do postLogin jest również zobowiązany do przekazania informacji o koszyku. Dla mnie jest to nadal spójne, kiedy widzisz, że są ze sobą powiązane. To połączenie zostanie wykonane przez dzwoniącego.

Wtedy nie musiałbyś nawet testować getShoppingCart wewnątrz postLogin, ponieważ prawdziwą testowaną metodą jest postLogin. Jest to ten, który ma błąd, i jedyny, który wymaga odpowiedniej naprawy i weryfikacji. Dzięki wstrzykniętej zależności będziesz mógł ją łatwo przetestować w różnych warunkach i potwierdzić, że nie zostanie zgłoszony żaden błąd.

gumol
źródło