Brug af Mockito ArgumentCaptor

1. Oversigt

I denne vejledning dækker vi et almindeligt anvendelses tilfælde af brug af Mockito ArgumentCaptor i vores enhedstest.

Alternativt for andre Mockito. Verificer brugssager, se vores Mockito Verify Cookbook.

2. Brug ArgumentCaptor

ArgumentCaptor giver os mulighed for at fange et argument, der er sendt til en metode for at inspicere det. Det her er især nyttigt, når vi ikke kan få adgang til argumentet uden for den metode, vi gerne vil teste.

Overvej f.eks. En EmailService klasse med en sende metode, som vi gerne vil teste:

offentlig klasse EmailService {privat DeliveryPlatform platform; offentlig EmailService (DeliveryPlatform platform) {this.platform = platform; } offentlig tomrumsudsendelse (streng til, strengemne, strengtekst, boolsk html) {Formatformat = Format.TEXT_ONLY; hvis (html) {format = Format.HTML; } E-mail-e-mail = ny e-mail (til, emne, brødtekst) email.setFormat (format); platform.deliver (e-mail); } ...}

I EmailService.sende, bemærk hvordan platform.leverer tager en ny E-mail som et argument. Som en del af vores test vil vi gerne kontrollere, at formatfeltet for det nye E-mail er indstillet til Format.HTML. For at gøre dette er vi nødt til at fange og inspicere det argument, der sendes til platform.leverer.

Lad os se, hvordan vi kan bruge ArgumentCaptor for at hjælpe os.

2.1. Opsæt enhedstesten

Lad os først oprette vores enhedstestklasse:

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

Vi bruger @Mock kommentar til at spotte Leveringsplatform, som automatisk injiceres i vores EmailService med @InjectMocks kommentar. Se vores Mockito-annotationsartikel for yderligere detaljer.

2.2. Tilføj en ArgumentCaptor Mark

For det andet, lad os tilføje et nyt ArgumentCaptor felt af typen E-mail at gemme vores fangede argument:

@Captor ArgumentCaptor emailCaptor;

2.3. Fang argumentet

For det tredje, lad os bruge Mockito. Verificer med ArgumentCaptor at fange E-mail:

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

Vi kan derefter få den fangede værdi og gemme den som en ny E-mail objekt:

E-mail emailCaptorValue = emailCaptor.getValue ();

2.4. Undersøg den indfangede værdi

Lad os endelig se hele testen med en påstand om at inspicere den fangede E-mail objekt:

@Test offentligt ugyldigt nårDoesSupportHtml_expectHTMLEmailFormat () {String to = "[email protected]"; Strengemne = "Brug af ArgumentCaptor"; String body = "Hej, lad os bruge ArgumentCaptor"; emailService.send (til, emne, krop, sandt); Mockito.verify (platform) .deliver (emailCaptor.capture ()); E-mail-værdi = emailCaptor.getValue (); assertEquals (Format.HTML, value.getFormat ()); }

3. Undgå stubbing

Selvom vi kan bruge en ArgumentCaptor med stubning, vi bør generelt undgå at gøre det. For at præcisere i Mockito betyder dette generelt at undgå at bruge en ArgumentCaptor med Mockito. Når. Ved stubning skal vi bruge en ArgumentMatcher i stedet.

Lad os se på et par grunde til, at vi skal undgå at stubbe.

3.1. Nedsat testlæsbarhed

Overvej først en simpel test:

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

Her bruger vi Mockito.eq (legitimationsoplysninger) for at angive, hvornår mocken skal returnere et objekt.

Overvej derefter den samme test ved hjælp af en ArgumentCaptor i stedet:

Credentials credentials = new Credentials ("baeldung", "correct_password", "correct_key"); Mockito.when (platform.authenticate (credentialsCaptor.capture ())) .thenReturn (AuthenticationStatus.AUTHENTICATED); assertTrue (emailService.authenticatedSuccessfully (legitimationsoplysninger)); assertEquals (credentials, credentialsCaptor.getValue ());

I modsætning til den første test skal du bemærke, hvordan vi skal udføre en ekstra påstand på den sidste linje for at gøre det samme som Mockito.eq (legitimationsoplysninger).

Endelig skal du bemærke, hvordan det ikke umiddelbart er klart, hvad credentialsCaptor.capture () refererer til. Dette skyldes, at vi er nødt til at oprette fangeren uden for den linje, vi bruger den på, hvilket reducerer læsbarheden.

3.2. Reduceret defekt Lokalisering

En anden grund er, at hvis emailService.authenticatedSuccessfully ringer ikke platform. godkende, får vi en undtagelse:

org.mockito.exceptions.base.MockitoException: Ingen argumentværdi blev fanget!

Dette skyldes, at vores stubede metode ikke har fanget et argument. Imidlertid er det faktiske problem ikke i selve vores test, men den egentlige metode, vi tester.

Med andre ord, det forkaster os til en undtagelse i testen, mens den faktiske fejl er i den metode, vi tester.

4. Konklusion

I denne korte vejledning kiggede vi på en generel anvendelse af brug ArgumentCaptor. Vi så også på grundene til at undgå at bruge ArgumentCaptor med stubning. Som normalt er alle vores kodeeksempler tilgængelige på GitHub.