Bruke Mockito ArgumentCaptor

1. Oversikt

I denne opplæringen vil vi dekke et vanlig brukstilfelle for bruk av Mockito ArgumentCaptor i enhetstestene våre.

Alternativt for andre Mockito.verify bruk tilfeller, se vår Mockito Verify Cookbook.

2. Bruke ArgumentCaptor

ArgumentCaptor tillater oss å fange et argument sendt til en metode for å inspisere det. Dette er spesielt nyttig når vi ikke får tilgang til argumentet utenfor metoden vi vil teste.

Tenk for eksempel på en EmailService klasse med en sende metode som vi ønsker å teste:

offentlig klasse EmailService {privat DeliveryPlatform-plattform; offentlig EmailService (DeliveryPlatform-plattform) {this.platform = plattform; } offentlig ugyldig sending (streng til, strengemne, strengtekst, boolsk html) {Formatformat = Format.TEXT_ONLY; hvis (html) {format = Format.HTML; } E-postadresse = ny e-postadresse (til, emne, kropp); email.setFormat (format); platform.deliver (e-post); } ...}

I EmailService.sende, legg merke til hvordan plattform. leverer tar en ny E-post som argument. Som en del av testen vil vi sjekke at formatfeltet til det nye E-post er satt til Format.HTML. For å gjøre dette, må vi fange og inspisere argumentet som sendes til plattform. leverer.

La oss se hvordan vi kan bruke ArgumentCaptor for å hjelpe oss.

2.1. Sett opp enhetstesten

La oss først lage vår enhetstestklasse:

@RunWith (MockitoJUnitRunner.class) offentlig klasse EmailServiceUnitTest {@Mock DeliveryPlatform-plattform; @InjectMocks EmailService emailService; ...}

Vi bruker @Håne kommentar til å spotte Leveringsplattform, som automatisk injiseres i vår EmailService med @InjectMocks kommentar. Se artikkelen om Mockito-merknader for ytterligere detaljer.

2.2. Legg til en ArgumentCaptor Felt

For det andre, la oss legge til en ny ArgumentCaptor felt av typen E-post for å lagre vårt fangede argument:

@Captor ArgumentCaptor emailCaptor;

2.3. Fang argumentet

For det tredje, la oss bruke Mockito.verify med ArgumentCaptor å fange E-post:

Mockito.verify (plattform) .deliver (emailCaptor.capture ());

Vi kan da få den fangede verdien og lagre den som en ny E-post gjenstand:

E-post emailCaptorValue = emailCaptor.getValue ();

2.4. Inspiser fanget verdi

Til slutt, la oss se hele testen med en påstand om å inspisere de fangede E-post gjenstand:

@Test offentlig ugyldig nårDoesSupportHtml_expectHTMLEmailFormat () {String to = "[email protected]"; Strengemne = "Bruk av ArgumentCaptor"; String body = "Hei, la oss bruke ArgumentCaptor"; emailService.send (til, emne, kropp, sant); Mockito.verify (plattform) .deliver (emailCaptor.capture ()); E-postverdi = emailCaptor.getValue (); assertEquals (Format.HTML, value.getFormat ()); }

3. Unngå stubbing

Selv om vi kan bruke en ArgumentCaptor med stubbing, vi bør generelt unngå å gjøre det. For å avklare, i Mockito, betyr dette vanligvis å unngå å bruke en ArgumentCaptor med Mockito. Når. Med stubbing, bør vi bruke en ArgumentMatcher i stedet.

La oss se på et par grunner til at vi bør unngå å stikke.

3.1. Redusert testlesbarhet

Først bør du vurdere en enkel test:

Legitimasjonsopplysninger = nye Legitimasjonsopplysninger ("baeldung", "correct_password", "correct_key"); Mockito.when (platform.authenticate (Mockito.eq (credentials))) .thenReturn (AuthenticationStatus.AUTHENTICATED); assertTrue (emailService.authenticatedSuccessfully (credentials));

Her bruker vi Mockito.eq (legitimasjon) for å spesifisere når spotten skal returnere et objekt.

Deretter vurderer du den samme testen ved hjelp av en ArgumentCaptor i stedet:

Legitimasjonsopplysninger = nye Legitimasjonsopplysninger ("baeldung", "correct_password", "correct_key"); Mockito.when (platform.authenticate (credentialsCaptor.capture ())) .thenReturn (AuthenticationStatus.AUTHENTICATED); assertTrue (emailService.authenticatedSuccessfully (credentials)); assertEquals (legitimasjon, legitimasjonCaptor.getValue ());

I motsetning til den første testen, legg merke til hvordan vi må utføre en ekstra påstand på den siste linjen for å gjøre det samme som Mockito.eq (legitimasjon).

Til slutt, legg merke til hvordan det ikke umiddelbart er klart hva credentialsCaptor.capture () refererer til. Dette er fordi vi må lage forfatteren utenfor linjen vi bruker den på, noe som reduserer lesbarheten.

3.2. Redusert feil Lokalisering

En annen grunn er at hvis emailService.authenticatedSuccessfully ringer ikke plattform. godkjenne, får vi et unntak:

org.mockito.exceptions.base.MockitoException: Ingen argumentverdi ble fanget!

Dette er fordi den stubbede metoden vår ikke har fanget et argument. Imidlertid er selve problemet ikke i selve testen vår, men den faktiske metoden vi tester.

Med andre ord, den fører oss feil til et unntak i testen, mens den faktiske feilen er i metoden vi tester.

4. Konklusjon

I denne korte opplæringen så vi på et generelt brukstilfelle for bruk ArgumentCaptor. Vi så også på årsakene til å unngå å bruke ArgumentCaptor med stubbing. Som vanlig er alle våre kodeeksempler tilgjengelig på GitHub.