Mock objektum
Az objektumorientált programozásban a mock objektumok más objektumok viselkedését utánozzák, de leegyszerűsítve. A minta a helyettes egy tesztelésre használt típusának tekinthető. Az autók tesztelésekor is töréstesztbábukat használnak emberek helyett. A mock objektumok alkalmazását mókolásnak is nevezik.
Használatának okai
[szerkesztés]Az egységtesztek egy fázisában a mock objektumok összetett, bonyolult viselkedéssel bíró objektumokat helyettesítenek olyan esetekben, amikor nem praktikus vagy lehetetlen az eredeti objektumokat használni. A következők esetén meggondolandó a mókolás:
- Az objektum nemdeterminisztikus eredményeket ad, például időtől vagy hőmérséklettől függően.
- Vannak állapotai, amelyek nehezen hozhatók létre, például hálózati hibák.
- Lassú, például egy komplett adatbázis.
- Még nincs, vagy a viselkedését még meg fogják változtatni.
- Csak a tesztelés számára fontos adatokat és metódusokat kívánunk használni.
Például egy ébresztőórának egy előre megadott időben kell csengetnie. Az időpontot a felhasználó fogja megadni. Ennek ellenőrzésére létrehoznak egy mock objektumot, ami kívánságra megcsengeti, így nem kell megvárni a kézzel megadott időt.
Tesztvezérelt fejlesztés
[szerkesztés]A tesztvezérelt fejlesztésben (TDD) mock objektumokat használnak a program írása közben, amikor a célobjektum még nincs megírva. A mock objektumok megvalósítják ugyanazt az interfészt, mint az eredeti, így tesztelhetők olyan funkciók is, amelyek komplex objektumokkal dolgoznának.[1] Így a programozók koncentrálhatnak a rendszer viselkedésére, amit így a függőségeitől izoláltan tudnak kezelni. Így vizsgálható önmagában egy algoritmus, ami összetett objektumokkal működik.
Amellett, hogy lehetővé teszi az egyes egységek önálló tesztelését, még fel is gyorsítja a folyamatot. A modern alkalmazások akár több száz egységet, modult is tartalmaznak. Ha ezek közül sok adatbázissal, webszolgáltatásokkal, más hálózati rendszerekkel vagy külső folyamatokkal kommunikál, akkor a valódi objektumokkal végzett tesztelés jelentősen lelassítja a folyamatot. Ez hanyagsághoz vezethet, és rossz szokásokat alakíthat ki.
A teszt egy későbbi szakaszában a mock objektumokat igaziakra kell cserélni, hogy teszteljék a vég-vég funkcionalitást. Ezek azonban már nem egységtesztek, hanem integrációs tesztek.
Technikai részletek
[szerkesztés]A mock objektumok, mint helyettesek megvalósítják a valódi objektum interfészét, így a kliens változtatás nélkül hívhatja a mock objektumot. Több keretrendszer is lehetővé teszi annak specifikálását, hogy a kliens milyen sorrendben és hányszor hívja a metódusokat. Az összetett objektum, mint egy hálózati socket viselkedése utánozható egy mock objektummal, így a programozó felismerheti, hogy az objektum az állapotának megfelelően válaszol-e.
Különböző helyettesek tesztelés közben
[szerkesztés]A mock, fake és stub objektumok osztályozása következetlen a szakirodalomban.[2][3][4][5][6][7] Az írók azonban egyetértenek abban, hogy ezek mind az eredeti objektum interfészét valósítják meg. Lehet szó összetettségről, például arról, hogy melyik dobhatja el a valódi objektum kivételeit. Az implementáció tartalmazhat állításokat (assert) is, amelyek a kontextust vizsgálják, vagy ellenőrzik az adatok megmaradását a hívások között. A spektrum egyik végén az összetett objektum áll, a másik végén pedig egy olyan, ami a publikus metódusok csak kiírnak valamit, például "almafa" vagy "vazz…".
A The Art of Unit Testing könyvben a mock objektumok fake objektumok, amelyek segítenek eldönteni, hogy egy teszt sikeres-e vagy sem, vagy verifikálja az objektumok interakcióit; minden más stub.[8] Itt a fake általában jelenti a tesztelésre használt helyettest.
Elvárások beállítása
[szerkesztés]Tekintsünk egy példát, amiben egy azonosító alrendszert mókolnak. A mock objektum implementál egy isUserAllowed(task : Task) : boolean
metódust, hogy egyezzen az eredeti osztállyal. Sok előnye van, ha felvesz egy isAllowed : boolean
tulajdonságot, ami nincs az eredeti osztályban. Itt be lehet állítani az elvárt értéket.
Hasonló beállításokkal elérhető, hogy kivétel dobódjon, null értéket adjon vissza, vagy elakadjon. Ezzel a kliens is felkészíthető ezekre az eseményekre. Ha a mock rendszer nem lenne egyszerű és rugalmas, akkor használhatatlan lenne.
Log szövegek
[szerkesztés]Egy mock ojektum save(person : Person)
metódusa nem végez valódi mentést, így nem biztos, hogy ellenőrzi az átadott objektum érvényességét, vagy azt, hogy nem null-e. Még ha ezeket ellenőrzi is, további implementációt nem tartalmazhat, és nem végezhet olyan ellenőrzéseket, hogy benne van-e már az adatbázisban, mert nem kapcsolódik az adatbázishoz.
Ez egy elszalasztott lehetőség. Az objektum naplózhatná a tevékenységét akár egy fájlba, akár egy nyilvános stringbe. A szöveg lehet egy rövid káromkodás, vagy utalhat a tevékenységre, esetleg tartalmazhatja a mentendő objektum azonosítóját.[1] A tesztkörnyezet vizsgálhatja a stringet, és ebből következtethet a működésre. Ezzel észrevehetők olyan jelenségek, amelyek csak a hatékonyságot csökkentik, például ugyanannak az adatnak többszöri elmentése, hogy ne vesszen el.
Korlátai
[szerkesztés]A mókolás megnövelheti a megírandó kód és a tesztek mennyiségét. Több keretrendszerben mérni lehet, hogy hányszor, milyen sorrendben hívták meg a műveleteket. Refaktoráláskor a kódot követve a mock objektumokat is refaktorálni kell; különben a tesztek jól futnak, de az eredeti kód hibáit nem tudja kiszűrni. Az egységteszteknek nem a belső működést, hanem a külső viselkedést kell vizsgálnia. A mock objektumok túlzott használata drámaian megnöveli a tesztek fenntartási költségét, mert ezt a refaktorálások megkövetelik. Ha ezt nem végzik megfelelően, akkor a tesztelés veszít hatékonyságából, nem kap el olyan bugokat, amelyeket megfelelő karbantartás esetén igen. Ha a mock objektumok generálhatók, akkor a fenntartás könnyen megoldható. Ezzel szemben egy metódus mókolása konfigurációt igényel, mint egy valódi osztály beállítása, ami csökkenti a fenntartás költségeit.
A mock objektumok modellezik annak az objektumnak a működését, amit mókolnak. Ez elég nehéz lehet, ha az még nem készült el, vagy más írja. Ha a viselkedés nincs megfelelően modellezve, akkor a teszt pontatlanabbá válik, és további tesztelésre lesz szükség akár a valódi objektumokkal.[9] Az interfészek és a dokumentáció pontos ismerete valamennyire segít az ügyben, de ez sem mindenható.
Jegyzetek
[szerkesztés]- ↑ a b Beck, Kent. Test-Driven Development By Example. Boston: Addison Wesley (2003). ISBN 0-321-14653-0
- ↑ Stubs and Mocks
- ↑ behind the times: Mocks and Stubs aren't Spies
- ↑ Mocks, Fakes, Stubs and Dummies at XUnitPatterns.com
- ↑ What's the difference between a mock & stub?
- ↑ What's the difference between faking, mocking, and stubbing?
- ↑ Feathers, Michael. Sensing and separation, Working effectively with legacy code. NJ: Prentice Hall, 23 et seq. o. (2005). ISBN 0-13-117705-2
- ↑ Osherove, Roy. Interaction testing with mock objects et seq, The art of unit testing. Manning (2009). ISBN 978-1-933988-27-6
- ↑ InJava.com to Mocking | O'Reilly Media
Fordítás
[szerkesztés]Ez a szócikk részben vagy egészben a Mock object című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.