Testy w Spring boot

0

Zastanawiam się, które metody z których klasy powinienem testować. Mam do wyboru :

service - jest tam cała logika, mieszają się różne service, wstrzykiwane jest dao,odbywają się zapisy do bazy itp
rest controller - wywoływane są tu metody service na odpowiednich url, ResponseEntity z HttpStatus i HttpHeaders .

2

Testy serwisów -> jednostkowe, mokujesz dao i sprawdzasz czy się dobrze wywołało i czy dobra logika zaszła
Testy DAO -> integracyjne, sprawdzasz czy faktycznie w bazie się zapisało (po teście rollback oczywiście)
Testy kontrolerów -> jednostkowe, trochę tam mockowania będzie, ale z pomocą przyjdzie mockMvc i wtedy sprawdzasz czy odpowiednie metody serwisowe się wywołują

0

ok czyli tak naprawdę prawie całą strukturę aplikacji:
dao,service i controller. A jakie narzędzie ? Ponieważ znam bardzo podstawy Spock i JUnit i chciałbym coś z tych dwóch poznać lepiej.

0

http://4programmers.net/Forum/Inzynieria_oprogramowania/276798-wstrzykiwanie_zaleznosci_a_testy_jednostkowe_-_zloty_srodek?start=20
tutaj masz dysputy na ten temat, problem w tym ze ciezko cos wywnioskowac, bo co czlowiek to trzy opinie.

0

Czy testy moga byc tranzakcyjne czy raczej powinno sie tego unikac?

0

@wartek01:
http://www.nurkiewicz.com/2011/11/spring-pitfalls-transactional-tests.html?m=1

Osobiscie wolalem miec transactional na serwisie. A testy tranzakcyjne to moim zdaniem czasem udawanie, ze cos dziala...

0
Bialy napisał(a):

@wartek01:
http://www.nurkiewicz.com/2011/11/spring-pitfalls-transactional-tests.html?m=1

Osobiscie wolalem miec transactional na serwisie. A testy tranzakcyjne to moim zdaniem czasem udawanie, ze cos dziala...

Nie do końca rozumiem. Co ma @Transactional w serwisie do testowania jedbostkowego?

Jeśli chcesz przetestować serwis to mockujesz DAO i testujesz na mocku (czy serwis wywołuje metodę z DAO z odpowiednim parametrem). Wtedy odcinasz się od dbania o zawartość bazy danych.

0

@wartek01:
No nie chodzi mi o testowanie jednostkowe a integracyjne.

I chodzilo mi o uzycie adnotacji @transactional na tescie. Co osobiscie mi sie nie podoba. Wole tylko na serwisie/dao cokolwiek ale nie tescie.

0

Biały, transkacje normalnie są na obiektach z logiką bizensową, ale jeśli mamy testy endpointowe zamiast jednostkowych to oznaczamy je @Transactional żeby po wykonaniu testu inserty, updaty i delejty się zrollbackowały ;)
Ogólnie to polecam Spocka i Grooviego to testów :)

0
scibi92 napisał(a):

Biały, transkacje normalnie są na obiektach z logiką bizensową, ale jeśli mamy testy endpointowe zamiast jednostkowych to oznaczamy je @Transactional żeby po wykonaniu testu inserty, updaty i delejty się zrollbackowały ;)
Ogólnie to polecam Spocka i Grooviego to testów :)

Wiem to wszystko.
Ale dalej nie raz mialem jakies problemy w stylu, ze test dzialal bo byla nad nim adnotacja transactional a w normalnej aplikacji okazywalo sie, ze cos jednak nie dziala. I ten transactional ukryl bląd.

0

Spock calkiem spoko ale groovy nie raz mnie poirytowal ;)

0

@scibi92 @wartek01
A moze odniesiecie sie do artykulu co wrzucilem?

A jakie zdanie ma @jarekr000000 albo @Shalom? ;)

0
Bialy napisał(a):
scibi92 napisał(a):

Biały, transkacje normalnie są na obiektach z logiką bizensową, ale jeśli mamy testy endpointowe zamiast jednostkowych to oznaczamy je @Transactional żeby po wykonaniu testu inserty, updaty i delejty się zrollbackowały ;)
Ogólnie to polecam Spocka i Grooviego to testów :)

Wiem to wszystko.
Ale dalej nie raz mialem jakies problemy w stylu, ze test dzialal bo byla nad nim adnotacja transactional a w normalnej aplikacji okazywalo sie, ze cos jednak nie dziala. I ten transactional ukryl bląd.

W jaki sposób transactional ukryl bląd ???? Nigdy nie miałem z tym problemów, oczywiście przed rollback flush

0

Masz w artykule @Szczery

2

Jeżeli już chcesz coś testować, to nie tak jak pisał @Pinek, bo to pisanie kolejnego zestawu testcasów dla Mockito.

Serwisy

Testujesz je jednostkowo, ale tylko gdy zawierają jakąś sensowna logikę. Serwis w postaci:

public void saveUser(User user){
	userDao.save(user);
}

Nie zawiera sensownej logiki. Serwis z sensowną, z punktu testów, logiką:

public void saveUser(User user){
	if(user.hasMinimumAge() && parentialService.verify(user)){
		userDao.save(user);
	} else{
		logging.cannotSave(user);
	}
}

Testujesz też wszelkiej maści złożone logiki. Dodatkowo nie weryfikujesz wywołania mocków, bo zmiana implementacji może za sobą pociągnąć np. zmianę liczby wywołań.

DAO

Jeżeli używasz Spring Data, to wystarczy smoke test, który sprawdza czy wstaje kontekst. Spring się wywali jeżeli nie będzie potrafił sparsować nazw metod w interfejsach. Jeżeli używasz zapytań JPQL, to testujesz je na poziomie integracyjnym. Jeżeli używasz native SQL, to mi nawet nie jest ciebie szkoda ;) Generalnie zapytania można testować w narzędziach dostawców baz danych.

Kontrolery

Po co? Kontrolery w Springu co do zasady nie zawierają testowalnej logiki i są tylko wejściami do systemu.

Testy integracyjne

Tu masz dwie grupy. Pierwsza to smoke testy. Czy wstaje kontekst (testujesz poprawność konfiguracji)? Czy poszczególne usługi odpowiadają, bo konfigurujemy je stringami i trzeba sprawdzić literówki? Czy nagłówki http są sensowne? Druga grupa to właściwe testy integracyjne. Testujesz tu jak współdziałają poszczególne komponenty. Osobiście piszę je „pod flow”, czyli wybieram sobie pojedynczy use case i w ramach testu integracyjnego „przeklikuję” go sprawdzając czy na różnych poziomach mam poprawne stany. Przy czym nie wnikam za bardzo w biznesową sensowność niektórych stanów. Testy integracyjne są też bazą do testów wydajnościowych.

Testy akceptacyjne

Osobna działka, na razie nie powinno cię to jakoś obchodzić.

0

@Koziołek:
A end to end? ;)

Ktos probowal zamiast Spring Daty wsadzac Concurrent Hash Mapie? ;)

0
Bialy napisał(a):

@Koziołek:
A end to end? ;)

Ktos probowal zamiast Spring Daty wsadzac Concurrent Hash Mapie? ;)

Pewnie, że próbował:
https://www.youtube.com/watch?v=ma15iBQpmHU

0
Koziołek napisał(a):

Jeżeli już chcesz coś testować, to nie tak jak pisał @Pinek, bo to pisanie kolejnego zestawu testcasów dla Mockito.

Serwisy

Testujesz je jednostkowo, ale tylko gdy zawierają jakąś sensowna logikę. Serwis w postaci:

public void saveUser(User user){
	userDao.save(user);
}

Nie zawiera sensownej logiki. Serwis z sensowną, z punktu testów, logiką:

public void saveUser(User user){
	if(user.hasMinimumAge() && parentialService.verify(user)){
		userDao.save(user);
	} else{
		logging.cannotSave(user);
	}
}

Testujesz też wszelkiej maści złożone logiki. Dodatkowo nie weryfikujesz wywołania mocków, bo zmiana implementacji może za sobą pociągnąć np. zmianę liczby wywołań.

DAO

Jeżeli używasz Spring Data, to wystarczy smoke test, który sprawdza czy wstaje kontekst. Spring się wywali jeżeli nie będzie potrafił sparsować nazw metod w interfejsach. Jeżeli używasz zapytań JPQL, to testujesz je na poziomie integracyjnym. Jeżeli używasz native SQL, to mi nawet nie jest ciebie szkoda ;) Generalnie zapytania można testować w narzędziach dostawców baz danych.

Kontrolery

Po co? Kontrolery w Springu co do zasady nie zawierają testowalnej logiki i są tylko wejściami do systemu.

Testy integracyjne

Tu masz dwie grupy. Pierwsza to smoke testy. Czy wstaje kontekst (testujesz poprawność konfiguracji)? Czy poszczególne usługi odpowiadają, bo konfigurujemy je stringami i trzeba sprawdzić literówki? Czy nagłówki http są sensowne? Druga grupa to właściwe testy integracyjne. Testujesz tu jak współdziałają poszczególne komponenty. Osobiście piszę je „pod flow”, czyli wybieram sobie pojedynczy use case i w ramach testu integracyjnego „przeklikuję” go sprawdzając czy na różnych poziomach mam poprawne stany. Przy czym nie wnikam za bardzo w biznesową sensowność niektórych stanów. Testy integracyjne są też bazą do testów wydajnościowych.

Testy akceptacyjne

Osobna działka, na razie nie powinno cię to jakoś obchodzić.

Wszystko co tu napisałeś zakłada że aplikacja nie robi nic i jest napisana w Springu XD generalnie ok.

0
Zimny Kret napisał(a):
Bialy napisał(a):

@Koziołek:
A end to end? ;)

Ktos probowal zamiast Spring Daty wsadzac Concurrent Hash Mapie? ;)

Pewnie, że próbował:
https://www.youtube.com/watch?v=ma15iBQpmHU

Pewnie o to Ci chodzilo, ale pytalem czy ktos jeszcze

0

@Szczery:
A niby dlaczego dtosy maja rozwiazywac te problemy?

1

@rubaszny_karp: większość aplikacji w Springu nic sensownego nie robi, bo to smutne CRUD aplikacje. Jak chcesz wrzucić do takiej aplikacji logikę, to zamykasz ją w osobnym projekcie/module i spring ją tylko wywołuje. Spring obecnie, to bardzo fajne narzędzie, do pisania szablonów, które karmisz logiką napisaną gdzie indziej.

@Rizorz: native queries, przesuwają logikę do bazy danych. Jeżeli dodatkowo opakujesz je w Stringa, to w praktyce zamiast statycznie i silnie typowanego kodu masz kod słabo i dynamicznie typowany, a dodatkowo ewaluowany w trakcie wykonania. Coś jak używanie eval w JS by wywołać kod jQuery.

0
Koziołek napisał(a):

@rubaszny_karp: większość aplikacji w Springu nic sensownego nie robi, bo to smutne CRUD aplikacje. Jak chcesz wrzucić do takiej aplikacji logikę, to zamykasz ją w osobnym projekcie/module i spring ją tylko wywołuje. Spring obecnie, to bardzo fajne narzędzie, do pisania szablonów, które karmisz logiką napisaną gdzie indziej.

Generalnie serwisy nic sensownego nie robią, tak naprawdę zamyka się logikę w bytecode-stream a potem ewentualnie na natywnym skomplikowanym JIT

ad. Endpointy

Oczywiście że piszemy testy, mamy małe mikroserwisy, do których łatwiej jest wrzucić prostą logike w endpoint na zasadzie : masz magic password ? to możesz dostać taki header w responsie - i to trzeba przetestować, tak samo required scopes na endpoint.

Jak chcesz wrzucić do takiej aplikacji logikę, to zamykasz ją w osobnym projekcie/module

@Koziołek - monolit is dead, zapomnij o tym.

0

@Koziołek - monolit is dead, zapomnij o tym.

Jesli chcesz każdą aplicakcje robic jako mikroserwisy to krzyżyk na droge.
Mikroserwisy są dużo trudniejsze niż monolit.I monolit ma się dobrze i będzie mial sie dobrze.

0
Biały mleczarz napisał(a):

@Koziołek - monolit is dead, zapomnij o tym.

Jesli chcesz każdą aplicakcje robic jako mikroserwisy to krzyżyk na droge.
Mikroserwisy są dużo trudniejsze niż monolit.I monolit ma się dobrze i będzie mial sie dobrze.

Oczywiście XD masz racje, są trudniejsze i ... droższe - operacyjność, zasoby ludzie to dodatkowe (i to nie małe) koszta - i nie miałem też na myśli że nagle wszyscy zaczną pisać aplikacje oparte o mikroserwisy. ALE - należy brać pod uwagę że nie każda aplikacja jest pisana jak dummy CRUD tak jak opisał to @Koziołek - i zamiast podążać za jakimiś zasadami (nie wiem skąd wzięte, jakaś biała księga testów ?) warto najpierw pomyśleć - jak można być dobrze przetestować moją aplikacje (myślenie > podążanie za kimś)

0

@rubaszny_karp: zdecydowana większość aplikacji springowych to smutne CRUD-y. Przez lata Spring był rozwijany w tym kierunku. Obecnie nie ma potrzeby testowania większości kodu, który powstaje z użyciem springowych zabawek. Jak pisałem wyżej to są zazwyczaj szablony, które wypełniasz logiką wziętą z innych modułów (monolity) albo ze specjalizowanych µSerwisów. Moduły springa pozwalają na bardzo szybką deweloperkę typowych aplikacji. Te aplikacje na prawdę nic nie robią poza zamianą reprezentacji danych.

Z drugiej strony piszę ostatnio mechanizm przewalutowań i spring poszedł w odstawkę, bo nie ma w nim nic, co mogło by nam się przydać. Nawet kontener DI okazał się zbędny, bo tylko utrudniał testowanie.

0
Koziołek napisał(a):

@rubaszny_karp: zdecydowana większość aplikacji springowych to smutne CRUD-y. Przez lata Spring był rozwijany w tym kierunku. Obecnie nie ma potrzeby testowania większości kodu, który powstaje z użyciem springowych zabawek. Jak pisałem wyżej to są zazwyczaj szablony, które wypełniasz logiką wziętą z innych modułów (monolity) albo ze specjalizowanych µSerwisów. Moduły springa pozwalają na bardzo szybką deweloperkę typowych aplikacji. Te aplikacje na prawdę nic nie robią poza zamianą reprezentacji danych.

Z drugiej strony piszę ostatnio mechanizm przewalutowań i spring poszedł w odstawkę, bo nie ma w nim nic, co mogło by nam się przydać. Nawet kontener DI okazał się zbędny, bo tylko utrudniał testowanie.

to czego uzywacie?

0

Do części „algorytmicznej” javy z vavrem i guavą. Do części bazodanowej JOOQ, a do obsługi komunikacji ze światem aerona. Co zabawne aeron bazuje na UDP, co powinny sprawiać problemy, ale jakoś nie mieliśmy jeszcze fakapu.

0
Koziołek napisał(a):

Do części „algorytmicznej” javy z vavrem i guavą. Do części bazodanowej JOOQ, a do obsługi komunikacji ze światem aerona. Co zabawne aeron bazuje na UDP, co powinny sprawiać problemy, ale jakoś nie mieliśmy jeszcze fakapu.

aeron, pierwsze slysze. Poczytam.

to jooq macie wykupione czy starcza Wam ta wersja 'free' ?

0

JOOQ starczy free, bo używamy Postgresa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1