Open skokoban opened 2 years ago
@skokoban nemyslim si, ze to funguje.
Mockito ti vyrobi object (napr. ten librinostriMock
). Na nem si potom mozes zavolat parseDownloadLinks
a vyrobi ti to, co chces. Iba ty si robis uplne inaci objekt tu:
https://github.com/skokoban/LibrinostriCzDownloader/blob/b5cb5c3f875c04c4f1acbb57f5eb758a6899d846/src/test/java/main/LibrinostriTest.java#L52
keby sa pouzil librinostriMock
, tak by to fungovalo s mockem.
Rovnako pri bookMock
u - ten sa nikde nepredava, tak sa ten mock ani nepouzije a je vlastne nanic.
Na test, ci ti to funguje je aspon pri pisani testu vhodne preklopit tam assertion - ci to spadne jak chces a ma naozaj to, co chces.
Ty si inac v LibrinostriTest v mocku pouzivas vrateni prazdneho rssDocument - ono je lepsi tam vratit neco, co sa podoba produkcnemu. A idealne neco, kde bude jasne, ze to neni z produkcie - aby ti bylo jasne, ze netestujes co chces testovat.
Inac s tym mockovanim SAXBuilderu - toto ta dovede k temu, ze to treba napisat trochu inac, aby sa to dalo testovat. Napr. ze sa bude SAXBuilder davat jak volitelny parameter v konstruktori. Alebo bude tato trida iba spracovavat RSS data, ale dostane ich od nekoho druheho.
Dalsi poznamky (iba take postrehy):
Dakujem za rady.
Inac s tym mockovanim SAXBuilderu - toto ta dovede k temu, ze to treba napisat trochu inac, aby sa to dalo testovat. Napr. ze sa bude SAXBuilder davat jak volitelny parameter v konstruktori. Alebo bude tato trida iba spracovavat RSS data, ale dostane ich od nekoho druheho.
Na tento problem, ze sa mi tazko testuje narazam uz nejaku dobu. Testy mam zlozite lebo musim vytvorit plno objektu, ktore ta testovana metoda potrebuje. Stale ale nechapem kde je jadro problemu. Myslel sem, ze si pomozem tym mockovanim.
Neni mi jasne proc mi pomoze ked objekt predam testovanej tride cez konstruktor oproti temu ked si zavolam testovanu metodu z testovanej tridy s tym, ze objekty tam dodam nejako inako. V kazdem pripade mi pride, ze tie objekty musim v testovacej triede vytvorit nech uz ich predavam ako parameter do konstruktora alebo inak - ako som to robil doteraz.
Myslim aj, ze to automaticke spustanie metod, ktore mam napr. v konstruktore Librinostri() tiez nieje dobre pre testovanie- ked sa mi tam zbytocne spustaju vselijake metody. - Tuto vec som zas pochytil na videu z prednasky programovania na STU. Ten ucitel daval ziakom zadanie, ze nechce vidiet ziadne volanie metod na objekte ale ma sa to same spravit len zavolanim konstruktora. Ked tak nad tym rozmyslam tak ma napadlo, ze im to povedal len z edukativnych ucelov a ked sa pohnu dalej v ucive tak im povie, ze spravne sa to ma rovit inak.
Ked si k tomu budem chciet precitat nejaky tutorial, je to ten termin dependency injection?
S tym, ze to nefunguje mas samozrejme pravdu- netestovalo mi to co som chcel. Musim to mockito este poskusat na jednoduchsich prikladoch lebo nerozumiem zatial ako to ma fungovat.
Testy mam zlozite lebo musim vytvorit plno objektu, ktore ta testovana metoda potrebuje.
No, to je prave cele o tem, jak to navrhnut, aby islo o minimalny interface. Ty to mas dost prepletene.
Priklad jak to "rozmotat":
public static
metody; take ale rovnako treba testovat.Teda chcem stahovat to, co bude v RSS. Tu to opisem mozno trochu detailnejsi:
Potom budes mnet nekde kod jak toto (zjednodusene a nazvy su trochu delsi pro nazornost; moje pevne stringy by mohli byt parametre funkcie alebo konstanty):
String rss = download("http://libri.../neco");
List<Book> allBooks = getAllBooksFromRSS(rss);
Map<String, String> allBooksUrlToFilename = getDownloadLocations(allBooks, "/home/peto/Download");
Map<String, String> notDownloadedBooksUrlToFilename = excludeExistingTargets(allBooksUrlToFilename);
downloadSourceDestination(notDownloadedBooksUrlToFilename);
Toto ma tu vyhodu, ze sa to cita dobre a nezanedbatelna cast sa da testovat lahko. Casti jak downloadSourceDestination
a download
s velku pravdepodobnostu uz nekdo naprogramoval tak, ze sa robia aj paralelne a efektivne. Alebo ich lahko urobis aj ty a nemaju moc spolecne s tvojim projektem - mozes ich pouzit aj inde. Mozno je to podobne aj pri excludeExistingTargets
.
Na zamysleni: mozno ma byt getDownloadLocations
mapa, kde je poradi naopak - subor je jak zdroj mapy. Nech sa da jedna URL stahnut aj na 2 rozlicne cile. Neupravoval sem to, ale je to asi este lepsi moznost.
Ano, poskytnuti treba downloadera sa vola dependency injection. Ale jak vidis, tak na test 3 z 5 metod (vlastne vsetkych s nejaku logiku) to vubec netreba - rovnako netreba ani mockovani.
volanie metod v konstruktori
Ano, to je casto zle - lebo mas este neskonstruovany objekt a volas v nom nieco. To nieco potom moze padnut, ked si na to nedas pozor.
V kazdem pripade mi pride, ze tie objekty musim v testovacej triede vytvorit nech uz ich predavam ako parameter do konstruktora alebo inak - ako som to robil doteraz.
Ano.
Musim to mockito este poskusat na jednoduchsich prikladoch lebo nerozumiem zatial ako to ma fungovat.
Mockito ti vrati objekt, u ktoreho nahradi jednu alebo viac metod. Ten objekt musis stale pouzivat. Neurobi "zazraky", ze by sa ten objekt automaticky dostal do tvojho vlastneho kontruktoru alebo podobne. Ked ho tam strcis, tak ano, ale to je tvoja akcia.
Čau, prosím ťa o radu ako si poradiť s týmto testom. Cez mockito poviem aby pri zavolaní metódy saveToHDD dodal moj pripravený objekt, aby sa nespúšťala tá originál metóda.Ale ono to ide stále do tej normál metódy. tento riadok to je: https://github.com/skokoban/LibrinostriCzDownloader/blob/b5cb5c3f875c04c4f1acbb57f5eb758a6899d846/src/test/java/tools/DownloaderTest.java#L60 Podobnú vec som písal v tomto istom projekte akurát som testoval inú triedu a tam to funguje podla mojho ocakavania: https://github.com/skokoban/LibrinostriCzDownloader/blob/b5cb5c3f875c04c4f1acbb57f5eb758a6899d846/src/test/java/main/LibrinostriTest.java#L50