Mockito vs EasyMock vs JMockit

1. Introduksjon

1.1. Oversikt

I dette innlegget skal vi snakke om gjøre narr av: hva det er, hvorfor bruke det og flere eksempler på hvordan man kan spotte den samme testsaken ved hjelp av noen av de mest brukte mocking-bibliotekene for Java.

Vi begynner med noen formelle / semi-formelle definisjoner av spottende begreper; så presenterer vi saken under test, følger opp eksempler for hvert bibliotek og ender med noen konklusjoner. De valgte bibliotekene er Mockito, EasyMock og JMockit.

Hvis du føler at du allerede vet det grunnleggende om å spotte, kan du kanskje hoppe til punkt 2 uten å lese de neste tre punktene.

1.2. Grunner til å bruke Mocks

Vi begynner å anta at du allerede koder etter noen drevne utviklingsmetoder sentrert på tester (TDD, ATDD eller BDD). Eller bare at du vil lage en test for en eksisterende klasse som er avhengig av avhengigheter for å oppnå funksjonaliteten.

I alle fall, når vi skal teste en klasse, ønsker vi det test bare funksjonaliteten og ikke den avhengigheten (enten fordi vi stoler på implementeringen av dem, eller fordi vi tester det selv).

For å oppnå dette, må vi gi objektet under testen, en erstatning som vi kan kontrollere for den avhengigheten. På denne måten kan vi tvinge ekstreme returverdier, unntakskasting eller bare redusere tidkrevende metoder til en fast returverdi.

Denne kontrollerte erstatningen er håne, og det vil hjelpe deg å forenkle testkoding og redusere testutførelsestiden.

1.3. Spottkonsepter og definisjon

La oss se fire definisjoner fra en artikkel skrevet av Martin Fowler som oppsummerer det grunnleggende alle burde vite om spott:

  • Dummy gjenstander blir sendt rundt, men blir aldri brukt. Vanligvis brukes de bare til å fylle parameterlister.
  • Forfalskning objekter har fungerende implementeringer, men tar vanligvis noen snarveier som gjør dem ikke egnet for produksjon (en i minnedatabase er et godt eksempel).
  • Stubber gi hermetiske svar på samtaler som er gjort under testen, og svarer vanligvis ikke i det hele tatt på noe utenfor det som er programmert for testen. Stubber kan også registrere informasjon om samtaler, for eksempel en e-post gateway-stub som husker meldingene den 'sendte', eller kanskje bare hvor mange meldinger den 'sendte'.
  • Håner er det vi snakker om her: objekter forhåndsprogrammert med forventninger som danner en spesifikasjon av samtalene de forventes å motta.

1.4 Å spotte eller ikke spotte: Det er spørsmålet

Ikke alt må hånes. Noen ganger er det bedre å gjøre en integrasjonstest da det å spotte den metoden / funksjonen bare ville fungere for liten faktisk fordel. I testtilfellet vårt (som vil bli vist i neste punkt) vil det være å teste Logg innDao.

De Logg innDao ville bruke noe tredjepartsbibliotek for DB-tilgang, og spotting av det ville bare bestå i å sikre at parametere var klargjort for samtalen, men vi trenger fortsatt å teste at samtalen returnerer dataene vi ønsket.

Av den grunn vil det ikke bli inkludert i dette eksemplet (selv om vi kunne skrive både enhetstesten med mock-samtaler for tredjepartsbibliotekssamtaler OG en integrasjonstest med DBUnit for å teste den faktiske ytelsen til tredjepartsbiblioteket).

2. Prøvesak

Med alt i forrige avsnitt i tankene, la oss foreslå en ganske typisk testtilfelle og hvordan vi tester den ved hjelp av mocks (når det er fornuftig å bruke mocks). Dette vil hjelpe oss til å ha et felles scenario for senere å kunne sammenligne de forskjellige spottende bibliotekene.

2.1 Forslag til sak

Den foreslåtte testsaken vil være påloggingsprosessen i en applikasjon med lagdelt arkitektur.

Innloggingsforespørselen blir håndtert av en kontroller som bruker en tjeneste som bruker en DAO (som ser etter brukerlegitimasjon på en DB). Vi vil ikke utdype for mye i hvert lags implementering og vil fokusere mer på interaksjoner mellom komponentene av hvert lag.

På denne måten får vi en LoginController, a LoginService og en Logg innDAO. La oss se et diagram for avklaring:

2.2 Gjennomføring

Vi følger nå med implementeringen som brukes i testsaken, slik at vi kan forstå hva som skjer (eller hva som skal skje) på testene.

Vi starter med modellen som brukes til alle operasjoner, UserForm, som bare inneholder brukerens navn og passord (vi bruker modifikatorer for offentlig tilgang for å forenkle) og en getter-metode for brukernavn felt for å tillate spott for den eiendommen:

public class UserForm {public String password; offentlig String brukernavn; public String getUsername () {return username; }}

La oss følge med Logg innDAO, som vil være ugyldig med funksjonalitet, ettersom vi bare vil at metodene skal være der, slik at vi kan spotte dem når det er nødvendig:

public class LoginDao {public int login (UserForm userForm) {return 0; }}

Logg innDao vil bli brukt av LoginService i sin Logg Inn metode. LoginService vil også ha en setCurrentUser metode som returnerer tomrom for å teste den hånen.

offentlig klasse LoginService {privat LoginDao loginDao; privat streng gjeldende bruker; offentlig boolsk pålogging (UserForm userForm) {assert null! = userForm; int loginResults = loginDao.login (userForm); switch (loginResults) {case 1: return true; standard: return false; }} offentlig ugyldig setCurrentUser (streng brukernavn) {if (null! = brukernavn) {this.currentUser = brukernavn; }}}

Endelig, LoginController vil bruke LoginService for dens Logg Inn metode. Dette inkluderer:

  • et tilfelle der ingen anrop til den spottede tjenesten vil bli utført.
  • et tilfelle der bare en metode vil bli kalt.
  • et tilfelle der alle metoder vil bli kalt.
  • et tilfelle der unntakskasting vil bli testet.
public class LoginController {public LoginService loginService; offentlig strenginnlogging (UserForm userForm) {if (null == userForm) {return "FEIL"; } annet {boolsk logget; prøv {logget = loginService.login (userForm); } fange (Unntak e) {return "FEIL"; } hvis (logget) {loginService.setCurrentUser (userForm.getUsername ()); returner "OK"; } annet {returner "KO"; }}}}

Nå som vi har sett hva det er vi prøver å teste, la oss se hvordan vi vil spotte det med hvert bibliotek.

3. Testoppsett

3.1 Mockito

For Mockito bruker vi versjon 2.8.9.

Den enkleste måten å lage mocks på er via @Håne og @InjectMocks kommentarer. Den første vil lage en mock for klassen som brukes til å definere feltet, og den andre vil prøve å injisere de opprettet mocks i den merkede mocken.

Det er flere merknader som @Spion som lar deg lage en delvis mock (en mock som bruker den normale implementeringen i ikke-hånede metoder).

Når det er sagt, må du ringe MockitoAnnotations.initMocks (dette) før du utfører tester som vil bruke nevnte mocks for at alt dette “magiske” skal fungere. Dette gjøres vanligvis i en @Før kommentert metode. Du kan også bruke MockitoJUnitRunner.

offentlig klasse LoginControllerTest {@Mock private LoginDao loginDao; @Spy @InjectMocks privat LoginService spiedLoginService; @Mock privat LoginService loginService; @InjectMocks privat LoginController loginController; @Før offentlig ugyldig setUp () {loginController = ny LoginController (); MockitoAnnotations.initMocks (dette); }}

3.2 EasyMock

For EasyMock bruker vi versjon 3.4 (Javadoc). Vær oppmerksom på at for mocks å begynne å "fungere" med EasyMock, må du ringe EasyMock.replay (mock) på hver testmetode, ellers får du et unntak.

Mocks og testede klasser kan også defineres via merknader, men i dette tilfellet, i stedet for å kalle en statisk metode for at den skal fungere, bruker vi EasyMockRunner for testklassen.

Mocks skapes med @Håne kommentar og det testede objektet med @Prøvekanin en (som vil få sine avhengigheter injisert fra opprettet mocks). Det testede objektet må opprettes online.

@RunWith (EasyMockRunner.class) offentlig klasse LoginControllerTest {@Mock privat LoginDao loginDao; @Mock privat LoginService loginService; @TestSubject privat LoginController loginController = ny LoginController (); }

3.3. JMockit

For JMockit bruker vi versjon 1.24 (Javadoc) ettersom versjon 1.25 ikke er utgitt ennå (i det minste mens du skriver dette).

Oppsett for JMockit er like enkelt som med Mockito, med unntak av at det ikke er noen spesifikk kommentar for delvis mocks (og egentlig ikke noe behov heller) og at du må bruke JMockit som testløper.

Mocks defineres ved hjelp av @Injiserbar kommentar (som vil opprette bare en hånlig forekomst) eller med @Latterliggjort kommentar (som vil skape spott for hver forekomst av klassen i det merkede feltet).

Den testede forekomsten blir opprettet (og de spottede avhengighetene injiseres) ved hjelp av @Testet kommentar.

@RunWith (JMockit.class) offentlig klasse LoginControllerTest {@Injectable private LoginDao loginDao; @Injiserbar privat LoginService loginService; @ Testet privat LoginController loginController; }

4. Bekrefte ingen samtaler til å spotte

4.1. Mockito

For å bekrefte at en mock ikke mottok anrop i Mockito, har du metoden verifiser ZeroInteractions () som godtar en hån.

@Test offentlig annullering assertThatNoMethodHasBeenCalled () {loginController.login (null); Mockito.verifyZeroInteractions (loginService); }

4.2. EasyMock

For å bekrefte at en mock ikke mottok noen anrop, spesifiserer du ganske enkelt ikke atferd, du spiller av mocken, og til slutt bekrefter du den.

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

4.3. JMockit

For å bekrefte at en mock ikke mottok samtaler, spesifiserer du ganske enkelt ikke forventningene til den mocken og gjør en FullVerifikasjoner (mock) for sagt hån.

@Test offentlig annullering assertThatNoMethodHasBeenCalled () {loginController.login (null); nye FullVerifications (loginService) {}; }

5. Definere samtale fra spottet metode og verifisere samtaler til spotter

5.1. Mockito

Til hånemetode samtaler, du kan bruke Mockito.when (mock.method (args)). DeretterReturn (verdi). Her kan du returnere forskjellige verdier for mer enn ett anrop, bare ved å legge dem til som flere parametere: thenReturn (verdi1, verdi2, verdi-n, ...).

Merk at du ikke kan spotte ugyldige returmetoder med denne syntaksen. I nevnte tilfeller vil du bruke en bekreftelse av metoden (som vist på linje 11).

Til bekrefte samtaler til en hån du kan bruke Mockito.verify (mock) .metode (args) og du kan også bekrefte at det ikke ble gjort flere anrop til en mock ved hjelp av verifisereNoMoreInteractions (mock).

Til bekreftende args, kan du overføre bestemte verdier eller bruke forhåndsdefinerte matchere som noen(), anyString (), anyInt (). Det er mye mer av den slags matchere og til og med muligheten til å definere matcherne dine, som vi vil se i følgende eksempler.

@Test offentlig tomrom assertTwoMethodsHaveBeenCalled () {UserForm userForm = ny UserForm (); userForm.username = "foo"; Mockito.when (loginService.login (userForm)). ThenReturn (true); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); Mockito.verify (loginService) .login (userForm); Mockito.verify (loginService) .setCurrentUser ("foo"); } @Test offentlig ugyldig påstandOnlyOneMethodHasBeenCalled () {UserForm userForm = new UserForm (); userForm.username = "foo"; Mockito.when (loginService.login (userForm)). ThenReturn (false); String login = loginController.login (userForm); Assert.assertEquals ("KO", innlogging); Mockito.verify (loginService) .login (userForm); Mockito.verifyNoMoreInteractions (loginService); }

5.2. EasyMock

Til hånemetode samtaler, du bruker EasyMock.expect (mock.method (args)). Og Retur (verdi).

Til bekrefte samtaler til en hån, kan du bruke EasyMock.verify (mock), men du må kalle det alltid etter ringer EasyMock.replay (mock).

Til bekreftende args, kan du overføre bestemte verdier, eller du har forhåndsdefinerte matchere som isA(Klasse klasse), anyString (), anyInt (), og mye mer av den slags matchere og igjen muligheten til å definere matcherne dine.

@Test offentlig tomrom assertTwoMethodsHaveBeenCalled () {UserForm userForm = ny UserForm (); userForm.username = "foo"; EasyMock.expect (loginService.login (userForm)). OgReturn (true); loginService.setCurrentUser ("foo"); EasyMock.replay (loginService); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); EasyMock.verify (loginService); } @Test offentlig ugyldig påstandOnlyOneMethodHasBeenCalled () {UserForm userForm = new UserForm (); userForm.username = "foo"; EasyMock.expect (loginService.login (userForm)). OgReturn (false); EasyMock.replay (loginService); String login = loginController.login (userForm); Assert.assertEquals ("KO", innlogging); EasyMock.verify (loginService); }

5.3. JMockit

Med JMockit har du definert trinn for testing: spille inn, spille på nytt og verifisere.

Ta opp er gjort i en ny Forventninger () {{}} blokk (hvor du kan definere handlinger for flere mocks), avspilling gjøres ganske enkelt ved å påkalle en metode av den testede klassen (som skal kalle et hånet objekt), og bekreftelse er gjort inne i en ny Bekreftelser () {{}} blokk (der du kan definere bekreftelser for flere mocks).

Til hånemetode samtaler, du kan bruke mock.methode (args); resultat = verdi; inne i noe Forventninger blokkere. Her kan du returnere forskjellige verdier for mer enn en samtale bare ved å bruke returnerer (verdi1, verdi2,…, verdi); i stedet for resultat = verdi;.

Til bekrefte samtaler til en hån kan du bruke nye bekreftelser() {{mock.call (verdi)}} eller nye bekreftelser (hån) {{}} for å bekrefte alle forventede samtaler som er definert tidligere.

Til bekreftende args, kan du sende spesifikke verdier, eller du har forhåndsdefinerte verdier som noen, anyString, anyLong, og mye mer av den slags spesielle verdier og igjen muligheten til å definere dine matchere (det må være Hamcrest-matchere).

@Test offentlig ugyldig assertTwoMethodsHaveBeenCalled () {UserForm userForm = new UserForm (); userForm.username = "foo"; nye forventninger () {{loginService.login (userForm); resultat = sant; loginService.setCurrentUser ("foo"); }}; String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); nye FullVerifications (loginService) {}; } @Test offentlig ugyldig påstandOnlyOneMethodHasBeenCalled () {UserForm userForm = new UserForm (); userForm.username = "foo"; nye forventninger () {{loginService.login (userForm); resultat = falsk; // ingen forventning for setCurrentUser}}; String login = loginController.login (userForm); Assert.assertEquals ("KO", innlogging); nye FullVerifications (loginService) {}; }

6. Spottende unntakskasting

6.1. Mockito

Kasting av unntak kan spottes ved hjelp av .thenTrow (ExceptionClass.class) etter en Mockito.when (mock.method (args)).

@Test offentlig ugyldig mockExceptionThrowin () {UserForm userForm = ny UserForm (); Mockito.when (loginService.login (userForm)). Deretter Kast (IllegalArgumentException.class); String login = loginController.login (userForm); Assert.assertEquals ("FEIL", innlogging); Mockito.verify (loginService) .login (userForm); Mockito.verifyZeroInteractions (loginService); }

6.2. EasyMock

Kasting av unntak kan spottes ved hjelp av .andThrow (ny ExceptionClass ()) etter en EasyMock.expect (…) anrop.

@Test offentlig ugyldig mockExceptionThrowing () {UserForm userForm = ny UserForm (); EasyMock.expect (loginService.login (userForm)). Og Kast (nytt IllegalArgumentException ()); EasyMock.replay (loginService); String login = loginController.login (userForm); Assert.assertEquals ("FEIL", pålogging); EasyMock.verify (loginService); }

6.3. JMockit

Spottende unntakskasting med JMockito er spesielt enkelt. Bare returner et unntak som et resultat av en hånet metodeanrop i stedet for "normal" retur.

@Test offentlig ugyldig mockExceptionThrowing () {UserForm userForm = ny UserForm (); nye forventninger () {{loginService.login (userForm); resultat = nytt IllegalArgumentException (); // ingen forventning for setCurrentUser}}; String login = loginController.login (userForm); Assert.assertEquals ("FEIL", innlogging); nye FullVerifications (loginService) {}; }

7. Spotte et objekt å passere rundt

7.1. Mockito

Du kan opprette en mock også å passere som et argument for en metodeanrop. Med Mockito kan du gjøre det med en one-liner.

@Test offentlig ugyldig mockAnObjectToPassAround () {UserForm userForm = Mockito.when (Mockito.mock (UserForm.class) .getUsername ()) .thenReturn ("foo"). GetMock (); Mockito.when (loginService.login (userForm)). ThenReturn (true); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); Mockito.verify (loginService) .login (userForm); Mockito.verify (loginService) .setCurrentUser ("foo"); }

7.2. EasyMock

Mocks kan opprettes på linje med EasyMock.mock (klasse.klasse). Etterpå kan du bruke EasyMock.expect (mock.method ()) å forberede den for utførelse, alltid huske å ringe EasyMock.replay (mock) før du bruker den.

@Test offentlig ugyldig mockAnObjectToPassAround () {UserForm userForm = EasyMock.mock (UserForm.class); EasyMock.expect (userForm.getUsername ()). OgReturn ("foo"); EasyMock.expect (loginService.login (userForm)). OgReturn (true); loginService.setCurrentUser ("foo"); EasyMock.replay (userForm); EasyMock.replay (loginService); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); EasyMock.verify (userForm); EasyMock.verify (loginService); }

7.3. JMockit

For å spotte et objekt for bare en metode, kan du bare sende det spottet som en parameter til testmetoden. Da kan du skape forventninger som med hvilken som helst annen mock.

@Test offentlig ugyldig mockAnObjectToPassAround (@Mocked UserForm userForm) {new Expectations () {{userForm.getUsername (); resultat = "foo"; loginService.login (userForm); resultat = sant; loginService.setCurrentUser ("foo"); }}; String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); nye FullVerifications (loginService) {}; nye FullVerifications (userForm) {}; }

8. Tilpasset argumentmatching

8.1. Mockito

Noen ganger må argumentmatching for spottede samtaler være litt mer komplisert enn bare en fast verdi eller anyString (). For de sakene har Mockito sin matcherklasse som brukes med argThat (ArgumentMatcher).

@Test offentlig ugyldig argumentMatching () {UserForm userForm = ny UserForm (); userForm.username = "foo"; // standard matcher Mockito.when (loginService.login (Mockito.any (UserForm.class))). thenReturn (true); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); Mockito.verify (loginService) .login (userForm); // complex matcher Mockito.verify (loginService) .setCurrentUser (ArgumentMatchers.argThat (new ArgumentMatcher () {@Override public boolean matches (String argument) {return argument.startsWith ("foo");}})); }

8.2. EasyMock

Tilpasset argumentmatching er litt mer komplisert med EasyMock, ettersom du trenger å lage en statisk metode der du oppretter selve matcheren og deretter rapporterer den med EasyMock.reportMatcher (IArgumentMatcher).

Når denne metoden er opprettet, bruker du den på din håne forventning med et kall til metoden (som vist i eksemplet i linjen).

@Test offentlig ugyldig argumentMatching () {UserForm userForm = ny UserForm (); userForm.username = "foo"; // standard matcher EasyMock.expect (loginService.login (EasyMock.isA (UserForm.class))). og Retur (true); // complex matcher loginService.setCurrentUser (specificArgumentMatching ("foo")); EasyMock.replay (loginService); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); EasyMock.verify (loginService); } privat statisk streng spesifikkArgumentMatching (streng forventet) {EasyMock.reportMatcher (ny IArgumentMatcher () {@Override offentlige boolske treff (Objektargument) {returargumentforekomst av String && ((Streng) argument) .startsWith (forventet);} @Override offentlig ugyldig appendTo (StringBuffer-buffer) {// NOOP}}); return null; }

8.3. JMockit

Tilpasset argumentmatching med JMockit gjøres med spesialen withArgThat (Matcher) metode (som mottar Hamcrest Matcher gjenstander).

@Test offentlig ugyldig argumentMatching () {UserForm userForm = ny UserForm (); userForm.username = "foo"; // standard matcher nye Expectations () {{loginService.login ((UserForm) any); resultat = sant; // complex matcher loginService.setCurrentUser (withArgThat (new BaseMatcher () {@Override public boolean matches (Object item) {return item instanceof String && ((String) item) .startsWith ("foo");} @ Overstyr offentlig ugyldig beskrivelse til) (Beskrivelse av beskrivelsen) {// NOOP}})); }}; String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); nye FullVerifications (loginService) {}; }

9. Delvis hån

9.1. Mockito

Mockito tillater delvis mocking (en mock som bruker den virkelige implementeringen i stedet for hånet metode kaller på noen av metodene) på to måter.

Du kan enten bruke .thenCallRealMethod () i en normal mock-metode samtalsdefinisjon, eller du kan opprette en spion i stedet for en hån, i hvilket tilfelle standard oppførsel for det vil være å kalle den virkelige implementeringen i alle ikke-hånede metoder.

@Test offentlig ugyldig partialMocking () {// bruk delvis mock loginController.loginService = spiedLoginService; UserForm userForm = ny UserForm (); userForm.username = "foo"; // la tjenestens pålogging bruke implementering, så la oss spotte DAO ring Mockito.when (loginDao.login (userForm)). thenReturn (1); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); // verifiser spottet samtale Mockito.verify (spiedLoginService) .setCurrentUser ("foo"); }

9.2. EasyMock

Delvis hån blir også litt mer komplisert med EasyMock, ettersom du må definere hvilke metoder som skal hånes når du lager mocken.

Dette er gjort med EasyMock.partialMockBuilder (Class.class) .addMockedMethod (“methodName”). CreateMock (). Når dette er gjort, kan du bruke mocken som hvilken som helst annen ikke-delvis mock.

@Test offentlig ugyldig partialMocking () {UserForm userForm = ny UserForm (); userForm.username = "foo"; // bruk delvis mock LoginService loginServicePartial = EasyMock.partialMockBuilder (LoginService.class) .addMockedMethod ("setCurrentUser"). createMock (); loginServicePartial.setCurrentUser ("foo"); // la tjenestens pålogging bruke implementering, så la oss spotte DAO ring EasyMock.expect (loginDao.login (userForm)). andReturn (1); loginServicePartial.setLoginDao (loginDao); loginController.loginService = loginServicePartial; EasyMock.replay (loginDao); EasyMock.replay (loginServicePartial); String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); // verifiser spottet samtale EasyMock.verify (loginServicePartial); EasyMock.verify (loginDao); }

9.3. JMockit

Delvis hån med JMockit er spesielt enkelt. Hver metodesamtale som ingen spottet oppførsel har blitt definert i Forventninger () {{}} bruker den “virkelige” implementeringen.

La oss forestille oss at vi delvis vil spotte LoginService klasse å spotte setCurrentUser () metoden mens du bruker den faktiske implementeringen av Logg Inn() metode.

For å gjøre dette oppretter og sender vi først en forekomst av LoginService til forventningsblokken. Da registrerer vi bare en forventning for setCurrentUser () metode:

@Test offentlig ugyldig partialMocking () {LoginService partialLoginService = ny LoginService (); partialLoginService.setLoginDao (loginDao); loginController.loginService = partialLoginService; UserForm userForm = ny UserForm (); userForm.username = "foo"; nye forventninger (partialLoginService) {{// la oss spotte DAO ring loginDao.login (userForm); resultat = 1; // ingen forventning om påloggingsmetode slik at reell implementering brukes // mock setCurrentUser call partialLoginService.setCurrentUser ("foo"); }}; String login = loginController.login (userForm); Assert.assertEquals ("OK", innlogging); // verifiser spottet samtale nye bekreftelser () {{partialLoginService.setCurrentUser ("foo"); }}; }

10. Konklusjon

I dette innlegget har vi sammenlignet tre Java-mock-biblioteker, hver med sine sterke sider og ulemper.

  • Alle tre er det enkelt å konfigurere med merknader som hjelper deg med å definere spott og objektet under test, med løpere for å gjøre spott injeksjon så smertefri som mulig.
    • Vi vil si at Mockito ville vinne her, siden den har en spesiell kommentar for delvise håner, men JMockit trenger ikke engang det, så la oss si at det er et slips mellom disse to.
  • Alle tre følger dem mer eller mindre post-reprise-verifiser mønster, men etter vår mening er den beste å gjøre det JMockit, da det tvinger deg til å bruke dem i blokker, slik at testene blir mer strukturerte.
  • Enkelhet bruk er viktig, slik at du kan jobbe så lite som mulig for å definere testene dine. JMockit vil være det valgte alternativet for sin faste-alltid-samme struktur.
  • Mockito er mer eller mindre DET mest kjente slik at samfunnet blir større.
  • Må ringe avspilling hver gang du vil bruke en mock er en klar Nei det går ikke, så vi setter minus en for EasyMock.
  • Konsistens / enkelhet er også viktig for meg. Vi elsket måten å returnere resultater av JMockit som er det samme for "normale" resultater som for unntak.

Vil alt dette bli sagt, skal vi velge JMockit som en slags vinner selv om vi til nå har brukt Mockito ettersom vi er blitt betatt av sin enkelhet og faste struktur og vil prøve å bruke den fra nå av.

De full gjennomføring av denne opplæringen finner du på GitHub-prosjektet, så last den gjerne ned og spill med den.


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