Piszę unit testy dla controllera w Java i springu. Prosty controller, ma swój endpoint i zwraca to co zwraca wywołanie serwisu. Coś w stylu
@GetMapping (blabla) @ResponseBody Public myObject myController() { return myService.getFoo() }
I teraz w teście mockuje sobie myService.getFoo() by zwrócił mi wcześniej przyszykowany myObject. Pytanie czy muszę temu zwracanemu obiektowi ustawiać wszystkie pola? (załóżmy, że ma ich 20).
Bo dyskutuję z kolegą. Według mnie nie ma co ustawiać wszystkich pól (czasami trzeba tworzyć kolejne obiekty), a wystarczy np. 2 najprostsze, bo chcę przetestować czy controller: - odpytuje poprawny endpoint - zwraca poprawny status - zwraca obiekt myObject i sprawdzam wyrywkowo te 2 pola (np. ID i name) - gdyby zwracał listę, to sprawdzilbym też jej wielkość
A nie chcę testować czy serwis np. nie pozamieniał czegoś w polach albo Jackson czegoś nie namiesza. Zakładam, że te rzeczy działają dobrze, a testuję tylko controller i jego zadanie.
Czy wy w testach controllerow ustawiacie wszystkie pola obiektu który zwraca zamocowany serwis czyli też controller?
Oczywiście inaczej wygląda sprawa gdyby w controllerze była dodatkowa logika, ale tutaj nie ma.
Pewnie rację ma kolega, a ja się mylę, ale chętnie posłucham argumentów za i przeciw bardziej doświadczonych #programista15k :D
@kaczoor: IMO jak testujesz serializację to każde pole a jak sprawdzasz, dla samego sprawdzania wartość którą sam przed chwilą ustawiłeś to w ogóle taka asercja jest zbędna, bo to robią testy w serwisie.
@kaczoor: pytanie: który komponent odpowiada za jacksona? Albo inaczej: wyobraź sobie, że ktoś złośliwy wrzuci jakieś bugi do jacksona, kto to ma wykryć?
Jeśli chodzi o test kontrolera to przetestowałbym z normalnych serwisem (bo po co mockować) tak, żeby przetestować wszystko co robi kontroler. Ponieważ to kontroler odpowiada za serializację do jsona to wypadałaboy przetestować wszystkie możliwe przypadki.
@prnppp: testuję kod w taki sposób jak ma działać. Jeśli używa on bibliotek to oczywiście, że tak. W jaki inny sposób mogę sprawdzić, czy używam biblioteki w dobry sposób? Albo, że aplikacja nie wysypie się po podbiciu wersji, bo kto wie co maintainer zmieni? Albo jak upewnić się, że zmiana biblioteki z A na B nie wprowadziła zmian funkcjonalnych
@prnppp: byłem raz w takim projekcie na którym były sprawdzane wywołania (czasami nawet wartość parametrów Captorem) i w moim odczuciu to zysk z tego był znikomy, bo było dużo więcej zachodu z utrzymaniem tych testów niż pożytku. Jeśli metoda dostawała nowe parametry albo w ogóle znikał interfejs to trzeba było poprawiać kilka albo kilkanaście testów, a jeśli projekt jest w początkowej fazie to na bank się dużo będzie zmieniać.
@kornfan: wydaje mi się, że jak to zwykle bywa w IT: to zależy. Unity na pewno są dobre, jeżeli jedynym źródłem logiki jest kod. Np. mamy 1kk bazę kodu, która nie woła żadnych serwisów i podprocesów i to co tam się dzieje to czyste algorytmy. Z drugiej strony im więcej integracji tym unity sprawiają się gorzej, bo mniej testują a mockowanie wkurza. Niestety/stety serwisy to zazwyczaj integracja z innymi usługami,
@Saly: testy jednostkowe są podstawą programowania, a ty najwyraźniej nie rozumiesz za bardzo idei testowania ani po co są mocki, co już wcześniej pokazałeś w pierwszym poście i testowaniu Jacksona xD
@prnppp: a kto tak powiedział? To, że ktoś kiedyś wymyślił kiedyś jakąś piramidę musi oznaczać automatycznie świętość? Takiego poziomu dogmatyzmu nie ma nawet w religiach
@prnppp: redukując do najbardziej absurdalnego przypadku. Masz SQLite, który najprawdopodobniej jest najlepiej przetestowanym softem na świecie. Czy te miliardy testów uchronią cię przed zrobieniem DROP TABLE users; w kodzie, który ma wyciągnąć dane z tabeli? Testowanie bitblioteki != testowanie użycia tej biblioteki. Przykład jacksona jest niefortunny, bo jako użytkownik tej libki masz mnóstwo małpek do wyboru, które mogą zmienić wynik końcowy. I bez testów "biblioteki" nie wykryjesz,
@GetMapping (blabla)
@ResponseBody
Public myObject myController() {
return myService.getFoo()
}
I teraz w teście mockuje sobie myService.getFoo() by zwrócił mi wcześniej przyszykowany myObject. Pytanie czy muszę temu zwracanemu obiektowi ustawiać wszystkie pola? (załóżmy, że ma ich 20).
Bo dyskutuję z kolegą. Według mnie nie ma co ustawiać wszystkich pól (czasami trzeba tworzyć kolejne obiekty), a wystarczy np. 2 najprostsze, bo chcę przetestować czy controller:
- odpytuje poprawny endpoint
- zwraca poprawny status
- zwraca obiekt myObject i sprawdzam wyrywkowo te 2 pola (np. ID i name)
- gdyby zwracał listę, to sprawdzilbym też jej wielkość
A nie chcę testować czy serwis np. nie pozamieniał czegoś w polach albo Jackson czegoś nie namiesza. Zakładam, że te rzeczy działają dobrze, a testuję tylko controller i jego zadanie.
Czy wy w testach controllerow ustawiacie wszystkie pola obiektu który zwraca zamocowany serwis czyli też controller?
Oczywiście inaczej wygląda sprawa gdyby w controllerze była dodatkowa logika, ale tutaj nie ma.
Pewnie rację ma kolega, a ja się mylę, ale chętnie posłucham argumentów za i przeciw bardziej doświadczonych #programista15k :D
#java #springboot #programowanie
To nie jest test obiektu myObject tylko kontrolera. Nie ma sensu na nim sprawdzać ani jednego pola bo testowanie mocka jest bezcelowe.
@kaczoor: pytanie: który komponent odpowiada za jacksona? Albo inaczej: wyobraź sobie, że ktoś złośliwy wrzuci jakieś bugi do jacksona, kto to ma wykryć?
Jeśli chodzi o test kontrolera to przetestowałbym z normalnych serwisem (bo po co mockować) tak, żeby przetestować wszystko co robi kontroler. Ponieważ to kontroler odpowiada za serializację do jsona to wypadałaboy przetestować wszystkie możliwe przypadki.
Za dużo przypadków? Możliwe, że testy na
@prnppp: +1
Bliżej
@prnppp: a kto tak powiedział? To, że ktoś kiedyś wymyślił kiedyś jakąś piramidę musi oznaczać automatycznie świętość? Takiego poziomu dogmatyzmu nie ma nawet w religiach
@prnppp: redukując do najbardziej absurdalnego przypadku. Masz SQLite, który najprawdopodobniej jest najlepiej przetestowanym softem na świecie. Czy te miliardy testów uchronią cię przed zrobieniem
DROP TABLE users;w kodzie, który ma wyciągnąć dane z tabeli? Testowanie bitblioteki != testowanie użycia tej biblioteki. Przykład jacksona jest niefortunny, bo jako użytkownik tej libki masz mnóstwo małpek do wyboru, które mogą zmienić wynik końcowy. I bez testów "biblioteki" nie wykryjesz,