Mockito vs EasyMock vs JMockit

1. Úvod

1.1. Prehľad

V tomto príspevku si povieme niečo o výsmech: čo to je, prečo to používať a niekoľko príkladov, ako sa vysmievať rovnakému testovaciemu prípadu pomocou niektorej z najbežnejších posmešných knižníc pre Javu.

Začneme niekoľkými formálnymi / poloformálnymi definíciami posmešných konceptov; potom predstavíme testovaný prípad, pokračujeme príkladmi pre každú knižnicu a nakoniec dospejeme k nejakým záverom. Vybraté knižnice sú Mockito, EasyMock a JMockit.

Ak máte pocit, že už viete, aké sú základné posmešky, môžete prejsť na bod 2 bez toho, aby ste si prečítali nasledujúce tri body.

1.2. Dôvody použitia makiet

Začneme predpokladať, že už programujete podľa nejakej riadenej vývojovej metodiky zameranej na testy (TDD, ATDD alebo BDD). Alebo jednoducho, že chcete vytvoriť test pre existujúcu triedu, ktorá sa pri dosahovaní svojej funkčnosti spolieha na závislosti.

V každom prípade, keď chceme testovať jednotku, chceme testujte iba jeho funkčnosť a nie závislosť (buď preto, že dôverujeme ich implementácii, alebo preto, že si to sami otestujeme).

Aby sme to dosiahli, musíme poskytnúť testovanému objektu náhradu, ktorú môžeme pre túto závislosť ovládať. Týmto spôsobom môžeme vynútiť extrémne návratové hodnoty, vyhadzovanie výnimiek alebo jednoducho znížiť časovo náročné metódy na pevnú návratovú hodnotu.

Táto kontrolovaná náhrada je predstieraťa pomôže vám to zjednodušiť kódovanie testu a skrátiť čas vykonania testu.

1.3. Vysmievané koncepty a definícia

Pozrime sa na štyri definície z článku, ktorý napísal Martin Fowler a v ktorom sú zhrnuté základné informácie, ktoré by mal každý vedieť o posmeškoch:

  • Dummy predmety sa míňajú okolo, ale nikdy sa v skutočnosti nepoužívajú. Spravidla sa používajú iba na vyplnenie zoznamov parametrov.
  • Falošné objekty majú funkčné implementácie, ale zvyčajne majú skratku, ktorá ich robí nevhodnými na výrobu (dobrým príkladom je pamäťová databáza).
  • Pahýly poskytujú konzervované odpovede na hovory uskutočnené počas testu, zvyčajne vôbec nereagujú na nič mimo toho, čo je naprogramované pre test. Zákazníci môžu tiež zaznamenávať informácie o hovoroch, ako napríklad problém s e-mailovou bránou, ktorý si pamätá správy, ktoré „odoslal“, alebo možno iba to, koľko správ „odoslal“.
  • Vysmievanie o čom tu hovoríme: objekty vopred naprogramované na očakávania, ktoré tvoria špecifikáciu hovorov, ktoré sa od nich očakáva.

1.4 Vysmievať sa alebo vysmievať sa: to je otázka

Nie všetko sa musí vysmievať. Niekedy je lepšie vykonať test integrácie, pretože posmeškom sa, že táto metóda / funkcia funguje len pre malý skutočný úžitok. V našom testovacom prípade (ktorý sa zobrazí v ďalšom bode), ktorý by testoval PrihlásenieDao.

The PrihlásenieDao použil by na prístup do databázy nejakú knižnicu tretej strany a zosmiešňovanie by spočívalo iba v zaistení toho, že parametre boli pre hovor pripravené, ale stále by sme potrebovali otestovať, či volanie vracia požadované údaje.

Z tohto dôvodu nebude v tomto príklade zahrnutý (aj keď by sme mohli napísať test jednotky s falošnými volaniami hovorov knižnice tretej strany A test integrácie s programom DBUnit na testovanie skutočného výkonu knižnice tretích strán).

2. Testovací prípad

Ak vezmeme do úvahy všetko, čo je uvedené v predchádzajúcej časti, navrhneme celkom typický testovací prípad a spôsob, ako ho budeme testovať pomocou falošných správ (keď má zmysel používať falošné testy). To nám pomôže mať spoločný scenár, aby sme neskôr mohli porovnávať rôzne posmešné knižnice.

2.1 Navrhovaný prípad

Navrhovaným testovacím prípadom bude proces prihlásenia do aplikácie s vrstvenou architektúrou.

Požiadavku na prihlásenie vybaví kontrolór, ktorý používa službu, ktorá používa DAO (ktorý hľadá prihlasovacie údaje používateľa v databáze). Nebudeme sa príliš zaoberať implementáciou jednotlivých vrstiev a zameriame sa viac na interakcie medzi zložkami každej vrstvy.

Týmto spôsobom budeme mať LoginController, a LoginService a a PrihlásenieDAO. Pozrime sa na diagram na objasnenie:

2.2 Implementácia

Teraz budeme postupovať podľa implementácie použitej v testovacom prípade, aby sme pochopili, čo sa v testoch deje (alebo čo by sa malo stať).

Začneme s modelom použitým pre všetky operácie, UserForm, ktorá bude obsahovať iba meno a heslo používateľa (na zjednodušenie používame modifikátory verejného prístupu) a metódu getter pre používateľské meno pole umožňujúce posmech pre túto vlastnosť:

verejná trieda UserForm {verejné reťazcové heslo; verejné meno používateľa reťazca; public String getUsername () {vrátiť používateľské meno; }}

Poďme s PrihlásenieDAO, to bude neplatné, pretože chceme, aby tu boli iba jeho metódy, aby sme ich v prípade potreby mohli zosmiešniť:

verejná trieda LoginDao {verejné int prihlásenie (UserForm userForm) {návrat 0; }}

PrihlásenieDao bude používaný LoginService v jeho Prihlásiť sa metóda. LoginService bude mať tiež a setCurrentUser metóda, ktorá sa vráti neplatný otestovať to posmešné.

verejná trieda LoginService {súkromné ​​LoginDao loginDao; private String currentUser; verejné logické prihlásenie (UserForm userForm) {assert null! = userForm; int loginResults = loginDao.login (userForm); switch (loginResults) {prípad 1: návrat true; predvolené: return false; }} public void setCurrentUser (meno používateľa reťazca) {if (null! = meno používateľa) {this.currentUser = meno používateľa; }}}

Nakoniec LoginController bude používať LoginService pre jeho Prihlásiť sa metóda. Bude to zahŕňať:

  • prípad, keď sa neuskutočnia žiadne hovory na vysmievanú službu.
  • prípad, v ktorom sa bude volať iba jedna metóda.
  • prípad, v ktorom sa budú volať všetky metódy.
  • prípad, v ktorom sa bude testovať vyhadzovanie výnimiek.
verejná trieda LoginController {public LoginService loginService; public String login (UserForm userForm) {if (null == userForm) {návrat "CHYBA"; } else {logicky logovany; skúste {loged = loginService.login (userForm); } catch (Výnimka e) {návrat "CHYBA"; } if (loged) {loginService.setCurrentUser (userForm.getUsername ()); návrat „OK“; } else {návrat "KO"; }}}}

Teraz, keď sme videli, čo to je, čo sa snažíme testovať, pozrime sa, ako si to budeme s každou knižnicou vysmievať.

3. Vyskúšajte nastavenie

3.1 Mockito

Pre Mockito budeme používať verziu 2.8.9.

Najjednoduchší spôsob vytvárania a používania simulov je prostredníctvom @Mock a @InjectMocks anotácie. Prvý vytvorí simuláciu pre triedu použitú na definovanie poľa a druhý sa pokúsi vložiť uvedené vytvorené simulácie do falošného komentára.

Existuje viac anotácií ako napr @ Spy , ktorý vám umožní vytvoriť čiastočný simulovaný model (simulovaný model, ktorý používa bežnú implementáciu v neposmievaných metódach).

To je povedané, musíte zavolať MockitoAnnotations.initMocks (toto) pred vykonaním akýchkoľvek testov, ktoré by použili uvedené výsmechy na to, aby celé toto „kúzlo“ fungovalo. Spravidla sa to deje v a @ Predtým komentovaná metóda. Môžete tiež použiť MockitoJUnitRunner.

verejná trieda LoginControllerTest {@Mock private LoginDao loginDao; @Spy @InjectMocks private LoginService spiedLoginService; @Mock private LoginService loginService; @InjectMocks private LoginController loginController; @ Pred verejnosťou void setUp () {loginController = nový LoginController (); MockitoAnnotations.initMocks (toto); }}

3.2 EasyMock

Pre EasyMock budeme používať verziu 3.4 (Javadoc). Upozorňujeme, že s programom EasyMock musíte zavolať, aby mohli simulátory začať „pracovať“ EasyMock.replay (falošné) pri každej testovacej metóde, inak dostanete výnimku.

Mocky a testované triedy je možné definovať aj pomocou anotácií, ale v takom prípade namiesto volania statickej metódy, aby to fungovalo, použijeme EasyMockRunner pre testovaciu triedu.

Vysmievanie sa vytvára pomocou @Mock anotácia a testovaný objekt s @TestSubject jeden (ktorý dostane svoje závislosti vložené z vytvorených falošných správ). Testovaný objekt musí byť vytvorený in-line.

@RunWith (EasyMockRunner.class) verejná trieda LoginControllerTest {@Mock súkromné ​​LoginDao loginDao; @Mock private LoginService loginService; @TestSubject private LoginController loginController = nový LoginController (); }

3.3. JMockit

Pre JMockit budeme používať verziu 1.24 (Javadoc), pretože verzia 1.25 ešte nebola vydaná (aspoň počas písania tohto textu).

Nastavenie pre JMockit je také ľahké ako v prípade Mockita, s výnimkou, že pre čiastočné falošné správy neexistuje žiadna konkrétna anotácia (a naozaj ani nie je potrebná) a že musíte JMockit ako testovací bežec.

Vysmievanie sa definuje pomocou @Injectable anotácia (ktorá vytvorí iba jednu simulovanú inštanciu) alebo s @Mocked anotácia (ktorá vytvorí zosmiešnenie pre každú inštanciu triedy anotovaného poľa).

Testovaná inštancia sa vytvorí (a jej falošné závislosti sa vložia) pomocou súboru @ Testované anotácia.

@RunWith (JMockit.class) verejná trieda LoginControllerTest {@Injectable private LoginDao loginDao; @Injectable private LoginService loginService; @ Vyskúšané súkromné ​​LoginController loginController; }

4. Overenie, že žiadne hovory nie sú falošné

4.1. Mockito

Na overenie toho, že falošný model v aplikácii Mockito neprišiel žiadny hovor, máte túto metódu verifyZeroInteractions () že prijíma faloš.

@Test public void assertThatNoMethodHasBeenCalled () {loginController.login (null); Mockito.verifyZeroInteractions (loginService); }

4.2. EasyMock

Na overenie toho, že falošný program neprijíma žiadne hovory, jednoducho neurčíte správanie, prehráte falošný program a nakoniec ho overíte.

@Test public void assertThatNoMethodHasBeenCalled () {EasyMock.replay (loginService); loginController.login (null); EasyMock.verify (loginService); }

4.3. JMockit

Na overenie toho, že falošný hráč neprijíma žiadne hovory, jednoducho neurčíte očakávania týkajúce sa tohto falošného výsledku a urobte Úplné overenia (falošné) pre spomínanú faloš.

@Test public void assertThatNoMethodHasBeenCalled () {loginController.login (null); nové FullVerifications (loginService) {}; }

5. Definovanie simulovaných volaní metód a overovanie hovorov simulátorom

5.1. Mockito

Pre posmešné volania metódy, môžeš použiť Mockito.when (mock.method (args)). ThenReturn (hodnota). Tu môžete vrátiť rôzne hodnoty pre viac ako jedno volanie iba ich pridaním ako ďalších parametrov: thenReturn (hodnota1, hodnota2, hodnota-n, ...).

Upozorňujeme, že pomocou tejto syntaxe nemôžete simulovať metódy vracania neplatných. V uvedených prípadoch použijete overenie uvedenej metódy (ako je uvedené na riadku 11).

Pre overovanie hovorov na predstieranie, ktoré môžete použiť Mockito.verify (falošný). Metóda (args) a tiež si môžete overiť, že s falošným používaním sa už neurobili žiadne hovory verifyNoMoreInteractions (falošný).

Pre overovacie argumenty, môžete odovzdať konkrétne hodnoty alebo použiť vopred definované zhody ako akýkoľvek(), anyString (), anyInt (). Existuje oveľa viac tohto druhu porovnávačov a dokonca aj možnosť definovať ich porovnávače, ktoré uvidíme v nasledujúcich príkladoch.

@Test public void assertTwoMethodsHaveBeenCalled () {UserForm userForm = nový UserForm (); userForm.username = "foo"; Mockito.when (loginService.login (userForm)). ThenReturn (true); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); Mockito.verify (loginService) .login (userForm); Mockito.verify (loginService) .setCurrentUser ("foo"); } @Test public void assertOnlyOneMethodHasBeenCalled () {UserForm userForm = nový UserForm (); userForm.username = "foo"; Mockito.when (loginService.login (userForm)). ThenReturn (false); Reťazec login = loginController.login (userForm); Assert.assertEquals ("KO", prihlásenie); Mockito.verify (loginService) .login (userForm); Mockito.verifyNoMoreInteractions (loginService); }

5.2. EasyMock

Pre posmešné volania metódy, používaš EasyMock.expect (falošná metóda (args)) a návrat (hodnota).

Pre overovanie hovorov na posmech, môžete použiť EasyMock.overiť (vysmievať sa), ale musíte to nazvať vždy po volanie EasyMock.replay (falošné).

Pre overovacie argumenty, môžete odovzdať konkrétne hodnoty alebo máte vopred definované zhody ako isA(Class.class), anyString (), anyInt (), a oveľa viac tohto druhu zhody a opäť možnosť definovať svoje zhody.

@Test public void assertTwoMethodsHaveBeenCalled () {UserForm userForm = nový UserForm (); userForm.username = "foo"; EasyMock.expect (loginService.login (userForm)). A návrat (true); loginService.setCurrentUser ("foo"); EasyMock.replay (loginService); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); EasyMock.verify (loginService); } @Test public void assertOnlyOneMethodHasBeenCalled () {UserForm userForm = nový UserForm (); userForm.username = "foo"; EasyMock.expect (loginService.login (userForm)). A návrat (false); EasyMock.replay (loginService); Reťazec login = loginController.login (userForm); Assert.assertEquals ("KO", prihlásenie); EasyMock.verify (loginService); }

5.3. JMockit

S JMockit ste definovali kroky pre testovanie: nahrávanie, prehrávanie a overovanie.

Záznam sa robí v novom Očakávania () {{}} blok (do ktorého môžete definovať akcie pre niekoľko simulov), repríza sa deje jednoducho vyvolaním metódy testovanej triedy (ktorá by mala volať nejaký vysmievaný objekt) a overenie sa robí vo vnútri nového Overenia () {{}} blok (do ktorého môžete definovať overenia pre niekoľko falošných správ).

Pre posmešné volania metódy, môžeš použiť falošná metóda (args); výsledok = hodnota; vo vnútri akejkoľvek Očakávania blokovať. Tu môžete vrátiť rôzne hodnoty pre viac ako jedno volanie iba pomocou výnosy (hodnota1, hodnota2, ..., hodnota); namiesto výsledok = hodnota;.

Pre overovanie hovorov na simuláciu môžete použiť nové Overenia() {{mock.call (hodnota)}} alebo nové overenia (simulované) {{}} na overenie každého predtým definovaného očakávaného hovoru.

Pre overovacie argumenty, môžete odovzdať konkrétne hodnoty alebo máte preddefinované hodnoty ako akýkoľvek, anyString, anyLong, a oveľa viac tohto druhu špeciálnych hodnôt a opäť možnosť definovať svoje porovnávače (to musia byť porovnávače Hamcrest).

@Test public void assertTwoMethodsHaveBeenCalled () {UserForm userForm = nový UserForm (); userForm.username = "foo"; new Expectations () {{loginService.login (userForm); výsledok = pravda; loginService.setCurrentUser ("foo"); }}; Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); nové FullVerifications (loginService) {}; } @Test public void assertOnlyOneMethodHasBeenCalled () {UserForm userForm = nový UserForm (); userForm.username = "foo"; new Expectations () {{loginService.login (userForm); výsledok = nepravda; // žiadne očakávanie pre setCurrentUser}}; Reťazec login = loginController.login (userForm); Assert.assertEquals ("KO", prihlásenie); nové FullVerifications (loginService) {}; }

6. Vysmievanie sa výnimkám

6.1. Mockito

Vrhačom výnimiek je možné sa vysmievať pomocou .thenThrow (ExceptionClass.class) po Mockito.when (mock.method (args)).

@Test public void mockExceptionThrowin () {UserForm userForm = nový UserForm (); Mockito.when (loginService.login (userForm)). ThenThrow (IllegalArgumentException.class); Reťazec login = loginController.login (userForm); Assert.assertEquals ("CHYBA", prihlásenie); Mockito.verify (loginService) .login (userForm); Mockito.verifyZeroInteractions (loginService); }

6.2. EasyMock

Hádzanie výnimiek je možné zosmiešňovať pomocou .andThrow (new ExceptionClass ()) po an EasyMock.expect (…) hovor.

@ Test public void mockExceptionThrowing () {UserForm userForm = nový UserForm (); EasyMock.expect (loginService.login (userForm)). A Throw (nový IllegalArgumentException ()); EasyMock.replay (loginService); Reťazec login = loginController.login (userForm); Assert.assertEquals ("CHYBA", prihlásenie); EasyMock.verify (loginService); }

6.3. JMockit

Obzvlášť ľahké je simulované vyhadzovanie s JMockitom. Stačí namiesto „normálneho“ návratu vrátiť výnimku ako výsledok falošného volania metódy.

@Test public void mockExceptionThrowing () {UserForm userForm = nový UserForm (); new Expectations () {{loginService.login (userForm); result = new IllegalArgumentException (); // žiadne očakávanie pre setCurrentUser}}; Reťazec login = loginController.login (userForm); Assert.assertEquals ("CHYBA", prihlásenie); nové FullVerifications (loginService) {}; }

7. Vysmievanie objektu, aby obišiel

7.1. Mockito

Môžete si vytvoriť falošnú správu, ktorá bude slúžiť ako argument pre volanie metódy. S Mockitom to zvládnete pomocou jednoradovej vložky.

@Test public void mockAnObjectToPassAround () {UserForm userForm = Mockito.when (Mockito.mock (UserForm.class) .getUsername ()) .thenReturn ("foo"). GetMock (); Mockito.when (loginService.login (userForm)). ThenReturn (true); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); Mockito.verify (loginService) .login (userForm); Mockito.verify (loginService) .setCurrentUser ("foo"); }

7.2. EasyMock

Vysmievanie je možné vytvárať priamo s EasyMock.mock (Class.class). Potom môžete použiť EasyMock.expect (mock.method ()) pripraviť ho na popravu a stále pamätať na to, aby ste zavolali EasyMock.replay (falošné) pred použitím.

@Test public void mockAnObjectToPassAround () {UserForm userForm = EasyMock.mock (UserForm.class); EasyMock.expect (userForm.getUsername ()). AndReturn ("foo"); EasyMock.expect (loginService.login (userForm)). A návrat (true); loginService.setCurrentUser ("foo"); EasyMock.replay (userForm); EasyMock.replay (loginService); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); EasyMock.verify (userForm); EasyMock.verify (loginService); }

7.3. JMockit

Ak chcete objekt vysmievať iba jednej metóde, môžete ho jednoducho poslať ako parameter testovacej metóde. Potom môžete vytvárať očakávania ako u každého iného falošného hráča.

@Test public void mockAnObjectToPassAround (@Mocked UserForm userForm) {new Expectations () {{userForm.getUsername (); výsledok = "foo"; loginService.login (userForm); výsledok = pravda; loginService.setCurrentUser ("foo"); }}; Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); nové FullVerifications (loginService) {}; nové FullVerifications (userForm) {}; }

8. Zhoda vlastných argumentov

8.1. Mockito

Niekedy musí byť porovnávanie argumentov pre vysmievané hovory trochu zložitejšie ako len pevná hodnota alebo anyString (). Pre tieto prípady má Mockito svoju triedu porovnávačov, ktorá sa používa s argThat (ArgumentMatcher).

@Test public void argumentMatching () {UserForm userForm = nový UserForm (); userForm.username = "foo"; // predvolený porovnávač Mockito.when (loginService.login (Mockito.any (UserForm.class)))). thenReturn (true); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); Mockito.verify (loginService) .login (userForm); // komplexný porovnávač Mockito.verify (loginService) .setCurrentUser (ArgumentMatchers.argThat (nový ArgumentMatcher () {@Override verejné boolean zápasy (argument reťazca) {return argument.startsWith ("foo");}}))); }

8.2. EasyMock

Vlastné porovnávanie argumentov je s EasyMockom o niečo komplikovanejšie, pretože je potrebné vytvoriť statickú metódu, pri ktorej vytvoríte skutočný porovnávač a potom ho nahlásite pomocou EasyMock.reportMatcher (IArgumentMatcher).

Akonáhle je táto metóda vytvorená, použijete ju na svoje falošné očakávanie s volaním metódy (ako je vidieť v príklade v riadku).

@Test public void argumentMatching () {UserForm userForm = nový UserForm (); userForm.username = "foo"; // default matcher EasyMock.expect (loginService.login (EasyMock.isA (UserForm.class))). andReturn (true); // komplexny matcher loginService.setCurrentUser (specificArgumentMatching ("foo")); EasyMock.replay (loginService); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); EasyMock.verify (loginService); } súkromný statický reťazec specificArgumentMatching (očakáva sa reťazec) {EasyMock.reportMatcher (nový IArgumentMatcher () {@Override verejné boolean zápasy (argument objektu) {návratový argument inštancie reťazca && ((reťazec) argument) .startsWith (očakáva sa);} @ verejná Verejnosť void appendTo (vyrovnávacia pamäť StringBuffer) {// NOOP}}); návrat null; }

8.3. JMockit

Vlastné porovnávanie argumentov s JMockitom sa vykonáva pomocou špeciálu withArgThat (Matcher) metóda (ktorá prijíma Hamcrestovu Matcher predmety).

@Test public void argumentMatching () {UserForm userForm = nový UserForm (); userForm.username = "foo"; // predvolený porovnávač new Expectations () {{loginService.login ((UserForm) any); výsledok = pravda; // komplexný porovnávač loginService.setCurrentUser (withArgThat (new BaseMatcher () {@Override public boolean Matchs (Object item) {return item instanceof String && ((String) item) .startsWith ("foo");} @Override public void describeTo (Popis popisu) {// NOOP}})); }}; Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); nové FullVerifications (loginService) {}; }

9. Čiastočné zosmiešňovanie

9.1. Mockito

Mockito umožňuje čiastočné zosmiešňovanie (falošné, ktoré v niektorých svojich metódach namiesto posmievaných volaní metód používa skutočnú implementáciu) dvoma spôsobmi.

Môžete použiť buď .thenCallRealMethod () v normálnej definícii simulovaného volania metódy, alebo môžete vytvoriť špión namiesto falošného, ​​v takom prípade bude predvoleným správaním volanie skutočnej implementácie vo všetkých metódach bez falošného výsledku.

@Test public void partialMocking () {// použiť čiastočné falošné loginController.loginService = spiedLoginService; UserForm userForm = nový UserForm (); userForm.username = "foo"; // nechajme prihlásenie pomocou služby implementáciu, tak si vysmejme DAO volanie Mockito.when (loginDao.login (userForm)). thenReturn (1); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); // overenie zosmiešňovaného hovoru Mockito.verify (spiedLoginService) .setCurrentUser ("foo"); }

9.2. EasyMock

Čiastočné zosmiešňovanie sa tiež s programom EasyMock trochu komplikuje, pretože musíte definovať, ktoré metódy sa budú vysmievať pri vytváraní zosmiešňovania.

Toto sa deje s EasyMock.partialMockBuilder (Class.class) .addMockedMethod („methodName“). CreateMock (). Keď je to hotové, môžete falošný model použiť ako akýkoľvek iný falošný model, ktorý nie je čiastočný.

@Test public void partialMocking () {UserForm userForm = nový UserForm (); userForm.username = "foo"; // použiť čiastočné falošné LoginService loginServicePartial = EasyMock.partialMockBuilder (LoginService.class) .addMockedMethod ("setCurrentUser"). createMock (); loginServicePartial.setCurrentUser ("foo"); // nechajme prihlásenie pomocou služby implementáciu, tak si vysmejme DAO volanie EasyMock.expect (loginDao.login (userForm)). andReturn (1); loginServicePartial.setLoginDao (loginDao); loginController.loginService = loginServicePartial; EasyMock.replay (loginDao); EasyMock.replay (loginServicePartial); Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); // overenie vysmievaného hovoru EasyMock.verify (loginServicePartial); EasyMock.verify (loginDao); }

9.3. JMockit

Obzvlášť ľahké je čiastočné zosmiešňovanie pomocou JMockit. Každé volanie metódy, pre ktoré nebolo definované žiadne zosmiešňujúce správanie Očakávania () {{}} používa „skutočná“ implementácia.

Teraz si predstavme, že sa chceme čiastočne vysmievať LoginService triedy na posmech setCurrentUser () metóda pri použití skutočnej implementácie Prihlásiť sa() metóda.

Aby sme to dosiahli, najskôr vytvoríme a odovzdáme inštanciu LoginService do bloku očakávaní. Potom zaznamenáme iba očakávanie týkajúce sa setCurrentUser () metóda:

@Test public void partialMocking () {LoginService partialLoginService = nový LoginService (); partialLoginService.setLoginDao (loginDao); loginController.loginService = partialLoginService; UserForm userForm = nový UserForm (); userForm.username = "foo"; new Expectations (partialLoginService) {{// zosmiešnime hovor DAO loginDao.login (userForm); výsledok = 1; // bez spôsobu prihlásenia sa neočakáva, aby sa použila skutočná implementácia // simulované volanie setCurrentUser partialLoginService.setCurrentUser ("foo"); }}; Reťazec login = loginController.login (userForm); Assert.assertEquals ("OK", prihlásenie); // verifikácia falošného hovoru new Verifications () {{partialLoginService.setCurrentUser ("foo"); }}; }

10. Záver

V tomto príspevku sme porovnávali tri falošné knižnice Java, z ktorých každá mala silné a slabé stránky.

  • Všetci traja sú ľahko konfigurovateľné s anotáciami, ktoré vám pomôžu definovať falošné a testované objekty, s bežcami urobia falošnú injekciu čo najmenej bolestivou.
    • Povedali by sme, že by tu Mockito zvíťazilo, pretože má špeciálnu anotáciu pre čiastočné výsmechy, ale JMockit to ani nepotrebuje, takže povedzme, že je to medzi týmito dvoma väzbami.
  • Všetci traja viac-menej nasledujú záznam-prehrať-overiť vzor, ale podľa nás je najlepším riešením JMockit, ktorý vás núti používať bloky v blokoch, takže testy budú štruktúrovanejšie.
  • Ľahkosť použitie je dôležité, aby ste pri definovaní svojich testov mohli pracovať čo najmenej. JMockit bude vybranou možnosťou pre jeho pevnú vždy rovnakú štruktúru.
  • Mockito je viac-menej NAJ známejšie, takže komunita bude väčší.
  • Musím volať repríza zakaždým, keď chcete použiť faloš, je jasné nechod, tak pre EasyMock dáme mínus.
  • Konzistencia / jednoduchosť je pre mňa tiež dôležitý. Páčil sa nám spôsob vrátenia výsledkov JMockit, ktorý je rovnaký pre „bežné“ výsledky ako pre výnimky.

Ak toto všetko bude povedané, vyberieme si JMockit ako druh víťaza, aj keď doteraz sme ich používali Mockito pretože nás zaujala jeho jednoduchosť a pevná štruktúra a odteraz sa ho pokúsime používať.

The úplná implementácia tohto tutoriálu nájdete v projekte GitHub, takže si ho môžete stiahnuť a hrať si s ním.


$config[zx-auto] not found$config[zx-overlay] not found