Mockito ArgumentMatchers

1. Oversigt

Denne tutorial viser hvordan man bruger ArgumentMatcher og hvordan det adskiller sig fra ArgumentCaptor.

For en introduktion til Mockito-rammen henvises til denne artikel.

2. Maven-afhængigheder

Vi er nødt til at tilføje en enkelt artefakt:

 org.mockito mockito-core 2.21.0 test 

Den seneste version af Mockito kan findes på Maven Central.

3. ArgumentMatchers

Det er muligt at konfigurere en hånet metode på forskellige måder. En af dem er at returnere faste værdier:

doReturn ("Flower"). når (flowerService) .analyse ("valmue");

I ovenstående eksempel er Snor "Blomst" returneres kun, når analysetjenesten modtager Snor "Valmue".

Men måske er vi nødt til at svare på et bredere spektrum af værdier eller på forhånd ukendte værdier.

I alle disse scenarier, vi kan konfigurere vores spottede metoder med argumentmatchere:

når (flowerService.analyze (anyString ())). derefterReturn ("Flower");

Nu på grund af anyString argument matcher, vil resultatet være det samme uanset hvilken værdi vi sender til at analysere. ArgumentMatchers giver os fleksibel verifikation eller stubbing.

I tilfælde af en metode har mere end et argument, det er ikke muligt at bruge ArgumentMatchers kun for nogle af argumenterne. Mockito kræver, at du angiver alle argumenter enten af matchere eller ved nøjagtige værdier.

Et næste eksempel er en forkert tilgang til dette:

abstrakt klasse FlowerService {public abstract boolean isABigFlower (String name, int petals); } FlowerService-mock = mock (FlowerService.class); når (mock.isABigFlower ("valmue", anyInt ())). derefter Retur (sand);

For at ordne det og beholde Snor navngiv “valmue”, som det ønskes, skal vi bruge eq matcher:

når (mock.isABigFlower (eq ("valmue"), anyInt ())). derefter Retur (sand);

Der er to punkter mere at passe på, når matchere er brugt:

  • Vi kan ikke bruge dem som en returværdi, kræves en nøjagtig værdi ved stubbing af opkald
  • Langt om længe, vi kan ikke bruge argument matchere uden for verifikation eller stubbing

I det sidste tilfælde Mockito vil opdage det misplacerede argument og kaste et InvalidUseOfMatchersException.

Et dårligt eksempel kan være:

String orMatcher = eller (eq ("valmue"), slutter med ("y")); verificere (mock) .analyse (ellerMatcher);

Måden at implementere ovenstående kode på er:

verificere (mock) .analyse (eller (eq ("valmue"), slutter med ("y")));

Mockito giver også AdditionalMatchers at implementere almindelige logiske operationer ('ikke', 'og', 'eller') på ArgumentMatchers der matcher både primitive og ikke-primitive typer:

verificere (mock) .analyse (eller (eq ("valmue"), slutter med ("y")));

4. Custom Argument Matcher

Opretter vores matcher kan være godt at vælge den bedst mulige tilgang til et givet scenario og producere test af højeste kvalitet, som er ren og vedligeholdelig.

For eksempel kunne vi have en MessageController der leverer beskeder. Den modtager en MessageDTO, og ud fra det vil det skabe en Besked leveres af MessageService.

Vores verifikation vil være enkel, kontroller at vi ringede til MessageService nøjagtigt 1 gang med enhver besked:

verificer (messageService, times (1)). deliverMessage (any (Message.class));

Fordi det Besked er konstrueret inde i den testte metode, vi er tvunget til at bruge nogen som den matcher.

Denne tilgang lader os ikke validere dataene inde i Besked, som kan være forskellige i forhold til dataene indeni MessageDTO.

Af den grund vil vi implementere en tilpasset argumentmatcher:

offentlig klasse MessageMatcher implementerer ArgumentMatcher {privat besked tilbage; // constructors @Override public boolean matches (Message right) {return left.getFrom (). equals (right.getFrom ()) && left.getTo (). equals (right.getTo ()) && left.getText (). er lig med (right.getText ()) && right.getDate ()! = null && right.getId ()! = null; }}

For at bruge vores matcher er vi nødt til at ændre vores test og udskifte nogen ved argThat:

verificer (messageService, times (1)). deliverMessage (argThat (new MessageMatcher (message)));

Nu kender vi vores Besked eksempel vil have de samme data som vores MessageDTO.

5. Custom Argument Matcher vs. ArgumentCaptor

Begge teknikker tilpassede argument matchere og ArgumentCaptor kan bruges til at sikre, at visse argumenter blev videregivet til mocks.

Imidlertid,ArgumentCaptor kan være en bedre pasform, hvis vi har brug for det for at hævde argumentværdier for at fuldføre verifikationen eller vores tilpasset argument matcher sandsynligvis ikke genbruges.

Tilpassede argument matchere via ArgumentMatcher er normalt bedre til stubning.

6. Konklusion

I denne artikel har vi udforsket en funktion af Mockito, ArgumentMatcher og dens forskel med ArgumentCaptor.

Som altid er den fulde kildekode for eksemplerne tilgængelig på GitHub.