Mock objektum

A Wikipédiából, a szabad enciklopédiából
Jump to navigation Jump to search

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ésteszt bá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]

  1. ^ a b Beck, Kent. Test-Driven Development By Example. Boston: Addison Wesley (2003). ISBN 0-321-14653-0 
  2. Stubs and Mocks
  3. behind the times: Mocks and Stubs aren't Spies
  4. Mocks, Fakes, Stubs and Dummies at XUnitPatterns.com
  5. What's the difference between a mock & stub?
  6. What's the difference between faking, mocking, and stubbing?
  7. Feathers, Michael. Sensing and separation, Working effectively with legacy code. NJ: Prentice Hall, 23 et seq. o. (2005). ISBN 0-13-117705-2 
  8. Osherove, Roy. Interaction testing with mock objects et seq, The art of unit testing. Manning (2009). ISBN 978-1-933988-27-6 
  9. 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.