Jól tervezett kód Mock/Stub-bal

Fórumok

A napokban létrehoztam egy blogbejegyzést: Mock & Stub, avagy hogyan tesztelünk rosszul tervezett kódot. Érdemes a videót (és esetleg a hozzászólásokat) megnézni!

Ott van egy nagyon jó videó Ken Scambler-től, aminek a végkövetkeztetése röviden ennyi:
Ha mock/stub kell a teszteléshez, akkor rosszul tervezett a kódom és érdemes áttervezni.

Egyik fórumtársunk szerint lehet jól tervezett kódunk akkor is, ha Mock/Stub kell a teszteléséhez.

Arra szeretném kérni minden programozó fórumtársamat, hogy ha tud ilyenre példát mutatni, akkor ne tartsa magában és ossza meg velünk!

Ui.: Kódot szeretnék kérni, akármilyet, akár pszeudo is lehet (legfeljebb nem értem meg :), és ne egy leírást adjatok.

Hozzászólások

halkan jegyzem meg (hogy ha valaki idetéved majd évek múlva, ne lásson egy teljesen egyoldalú véleményt), de szerintem mindenki megunta veled a végeláthatatlan vitát.
--
blogom

Akkor nem látna egy teljesen egyoldalú véleményt, ha legalább egy példakód idekerülne.
Ha így lesz, akkor ígérem leveszem a [Nem megoldható] feliratot.

"megunta veled a végeláthatatlan vitát."
Az is lehet, hogy így van (a részedről gondolom biztosan), de a magam részéről pl. azért nem írok semmi választ az utolsó bejegyzésekre, mert már többet nem tudok hozzátenni az előbbiekhez. Még az is lehet, hogy más is így van ezzel.

Remélem nem mindenki gondolja úgy, hogy értelmetlen vita lett volna, hanem inkább úgy, hogy a felek részéről hasznos gondolatok fogalmazódtak meg a vita során! Annál is inkább, mert mindenki próbálta a szakmai véleményét kifejteni és nem egyszerű sárdobálás ment.

Megjegyeznem (csak ha valaki idetevedne), hogy enpassantnak igaza van.

I/O-t mockolni/stubolni/test doubleni kell, hiszen azt az igazan koltseges tesztelni. Azon kivul viszont arra kell torekedni, hogy I/O muveletet minel kevesebb helyen hivjunk, igy minimalizalva a mockolni szukseges dolgok koret.

Szerintem meg pont a jól tervezett szoftvert lehet jól mockolni, ha a részei külön egységenként jól tesztelhető akkor jól is mockolható.

Példakódott meg azért nem írt ide senki mert három osztálynál még nem kell mockolni, harmincat senki nem fog pszeudó kódra alakítani hogy ide posztolja. Nem azért használ az ember mockot mert máshogy nem lehet tesztelni hanem mert megspórolja példányosítást ezáltal gyorsul a teszt.

===============================================================================
// Hocus Pocus, grab the focus
winSetFocus(...)

http://c2.com/cgi/wiki?FunnyThingsSeenInSourceCodeAndDocumentation

Köszi, ezek érdekesek!

[Szerkesztve]

Még ezt is érdemes megnézni (ugyanazon alomból van):
Loosely Coupled Tests

Elolvastam ezeket, megpróbálom összefoglalni a lényegüket.

"The Little Mocker" by Uncle Bob

Elmagyarázza, hogy mi micsoda.
Test doubles avagy tágabb ételemben Mock: Dummy, Stub, Spy, Mock és a Fake.
A Fake az kilóg a sorból, mert az az egyetlen, amelynek igazi üzleti viselkedése van.
"fakes have real business behavior; stubs do not. Indeed, none of the other test doubles we've talked about have real business behavior"
A Fake-kel a fő gond szerinte, hogy extrém komplikált lehet.
"They can get extremely complicated. So complicated they need unit tests of their own. At the extremes the fake becomes the real system."

Általában nem használ Mocking tool-okat, soha nem használ fake-et, a többit ritkán, akkor is kézzel írja (IDE-vel generálja a nagyját) és interface alapú.

"When to Mock" by Uncle Bob

Ha nem használunk Mock-ot, akkor az milyen gondokat okoz:
1) Nagyon lassú lehet a teszt, ha pl. adatbázis műveletek, külső service hívások, ... vannak.
2) A tesztelt kód lefedettsége (coverage) alacsony lehet. Veszélyes műveleteket, fájl vagy adatbázis törlés nehéz biztonságosan tesztelni nélküle.
3) A teszt érzékeny lehet olyan dolgokra, ami nincs kapcsolatban a tesztel. Pl. network timeout, adatbázisban nincs rekord vagy éppen van.

A túl sok Mock milyen gondokat okoz:
1) Némely Mocking rendszer reflection-t használ és ezért nagyon lassú lesz.
2) Az összes osztály közötti interakciók kimockolása miatt a mock-oknak más mock-ot kell visszaadjanak. Az összes adatútvonalat ki kell mockolni, ami nagyon komplex feladat és két problémát is okoz:
a) A beállító kód extrém komplikált lesz
b) A mock struktúra erősen össze lesz kötve az implementációval, emiatt sok teszt elromlik, ha az implementáció részletei változnak.
3) A létrehozandó interface-ek száma hatványozottan növekszik és ez tervezési hibát okoz.

Megoldás: az architekturálisan szignifikáns határok között kell csak mockolni, azokon belül nem. Pl. adatbázis, külső hívás kimockolása.

"Loosely Coupled Tests" by Chris Jordan

Mocking Collaborators

A Mocking library-kat gyorsan és könnyen lehet használni. Problémák ezzel:
- A mock setup-okat duplikálni kell sok helyre, ahol használva vannak. Emiatt, ha változik a mockolt objektum, akkor sok helyen kell a mock setup-ot átírni.
- Egy mock beállítása elég nagy mennyiségű is lehet, hogy az összes használt metódusnak legyen alapértelmezett viselkedése.

A megoldás szerinte az lehet, ha Fake-et használunk a Mock-ok helyett.

Loosely coupled data

Az adatokat sok esetben nem triviális inicializálni, pl. nagyon nagy mennyiségű adatot kell megadni. Sok esetben ezt Mock-kal oldják meg, ahol csak a szükséges mezőket definiálják. Ezzel az a probléma, hogy ha több adatot is meghív, akkor bővíteni kell a beállítások körét.

A másik megoldás az lehet, hogy a tényleges objektum használata, akkor viszont az összes mezőjét meg kell adni mindig. Erre viszont az lehet a megoldás, hogy egy központi helyen hozzuk létre és a nem szükséges minden adatot megadni, a hiányzókat default értékkel tölti ki.