"Ez az amikor az implementáció mikéntjét teszteled"
Errol szol az unit teszt, kedves.
A kalkulatoros peldadra: attol fugg, _mit_ szeretnek tesztelni. Ha a CalcService mukodeset (vagyis, hogy 2,3 parameterekre 5-ot ad-e vissza) akkor nem stubolnam ki, hiszen ez a CalcService unit tesztje, azt nem stubolom ki. Ha ellenben a BigComputationalService -nek a unit tesztjet hivom, es a CalcService az nem egy ilyen kis konstansokat osszeadogato olcso muveletekkel operalo cucc, hanem valami DB-kereseses tortenet, akkor bizony kistubolom a CalcService-t, espedig azert, mert nem vagyok hajlando a BigComputationalService unit tesztje moge DB-t rakni, akkor sem, ha szeretned.
"Csak kettőt kell karbantartan"
Az pont eggyel tobb, mint amennyit karban szeretnek tartani.
Valamit felreertesz: a stub-ok nem kulonallo entitasok, hanem a tesztek szerves reszei, a teszt osztalyaiban szerepelnek, az egyes tesztek inicializaljak fel es szuntetik meg oket. Egy kulon TestAuthService azonban nem lesz a tesztek resze, az egy plusz egy implementacio lesz, aminek unit tesztje nemigen, vagy alig lesz, es ha hozzanyulsz a TestAuthService-hez ugy, hogy megvaltoztatod valamely "egyszeru implementacio"-nak a logikajat (mert mondjuk erre van szukseg egy uj tesztnel), akkor a valtozast vegig kell vezetned a regi teszteken is, akkor is, ha azok az epp fejlesztett funkcionalitast baromira nem erintik. Raadasul a jo isten a megmondhatoja, hogy hany hibat lehet ilyenkor veteni.
A stubokat pont emiatt talaltak ki, mert igy annyi implementaciod lehet, amennyit akarsz, viszont az eppen tesztelt funkcionalitason kivul nem kell azzal torodnod, hogy a tobbi fuggveny mit ad vissza, mert a kutya nem fogja meghivni oket. Azzal kell torodnod, hogy az eppen aktualisan fejlesztett cucc hivasai jok legyenek, fuggony.
Nem mondom, hogy minden esetben stubolni/mockolni kell, de ha valami nem szamokkal, hanem objektumokkal dolgozik, es fuggosege van barmilyen kulso eroforras fele (LDAP szerver, adatbazis, SOAP/RPC service, barmi), akkor erdemesebb inkabb azokat a reszeket kifake-lni, mintsem annyira szetszervezni az alkalmazas strukturajat, hogy ne kelljen stubolni/mockolni. Nagyon nem mindegy ugyanis, hogy 100 vagy 1000 osztaly kozott kell tudni navigalni, a kompaktsag egy eleg lenyeges szempont. Raadasul a szamologepnel ket fokkal bonyolult alkalmazasnal mar alapbol tobbszaz osztaly kozott kell tajekozodni, felesleges ezt a szamot exponencialis novesztesnek alavetni. Es igen, persze, dokumentacio... de azt is meg kell valakinek irni.
"jól tervezett rendszernél ez összemosódik, ami jó."
Te meg nem lattal jol tervezett rendszereket. Az integracios es unit teszteket ott lehet osszemosni, ahol az app mogott nincs komolyabb logika egy szobanoveny mukodesenel. Locsol, fold, nap, novekszik, kesz. Ahol van ket szerviz meg harom modell objektum, es az egesz app ot oldalbol/kepernyobol all, fixen odaszogezett ertekekkel, gyakorlatilag egy CRUD interface. Na az ilyeneknel ossze lehet mosni az unit meg integracios reteget, ugyanis az unit teszttel gyakorlatilag semmi mast nem tesztelnel, mint az egesz mogott levo frameworkot, ami nem a te scope-d. Amint _barmilyen_ uzleti logika is mogekerul az appnak (riportolas, integracio, jogkezeles, automatizmusok, stb, stb, stb), NEM megkerulheto az integracios tesztek levalasztasa a unit tesztetktol. Ez ketto ok miatt van igy:
1) az uzleti logika specifikacionak megfelelo mukodeset tesztelni kell. Igen, ez gyakorlatilag az implementacio teszteleset jelenti. Ha az LDAPAuthService nem hiv ki az LDAP-ba, csak otletszeruen ad egy true-t az a vilagon senkinek nem jo, legfeljebb neked, mert "hat nezz oda, true lett a vege, akkor vegulis minden happy, nem?" Hat nagyon nem.
2) Muszaj tesztelni a valos szervizekkel valo egyuttmukodest is, mert lehet barmilyen "egyszeru implementaciod", ha az a ruhes LDAP/SQL/SOAP nem az elkepzeleseid szerint mukodik, es olyat ad vissza, amit az "egyszeru implementacio" nem (mert mondjuk a kulso gyarto fejlesztett a kulso service-n a tudtod nelkul), akkor az alkalmazas jo esetben megmakkan, rossz esetben a komplett uzleti logika felborul. Nagyon nehez az ilyen eseteket kimagyarazni. Es ma a cloud service-k vilagaban (ahol a tenyleges mukodes akar percszinten is valtozhat) ez baromira nem egy elszabadult otlet.
Es csak hogy tisztazzuk: en sem stubolnek/mockolnek ki mindent. Ez - mint minden mas fejlesztoi eszkoz - olyan cucc, amit esszel kell hasznalni, es mindig, kivetel nelkul mindig merlegelni kell a hasznalatat, az adott esethez kell merni. De kiallni, es olyat mondani, hogy a mocking es a stubbing az ordogtol valo, es mindenestul kerulendo, na az az ostobasag melysotet kutjaba vetett pillantassal er fel.
Egyebkent imadom, amikor egyszeru kis peldakat hoztok fel, amit ranezesre se akarna senki stubolni. A valos eletben sosem kell CalcService-ket irni, hanem mindg viszonylag bonyolult esetek vannak, harom-negy-ot uzleti objektum is reszt vesz a dologban, de mindenki nagyvonaluan azt mondja, hogy "de hat azokkal ugyanigy kell eljarni". Vagy nem.
--
Blog | @hron84
Üzemeltető macik