Bruke Hamcrest Number Matchers
1. Oversikt
Hamcrest tilbyr statiske matchere for å gjøre påstander om enhetstest enklere og mer leselig. Du kan komme i gang med å utforske noen av de tilgjengelige matcherne her.
I denne artikkelen vil vi dykke dypere inn i antall relaterte matchere.
2. Oppsett
For å få Hamcrest, trenger vi bare å legge til følgende Maven-avhengighet til vår pom.xml:
org.hamcrest java-hamcrest 2.0.0.0
Den siste Hamcrest-versjonen finner du på Maven Central.
3. Nærhetsmatchere
Det første settet med matchere som vi skal se på er de som sjekk om noe element er nær en verdi +/- en feil.
Mer formelt:
verdi - feil <= element <= verdi + feil
Hvis sammenligningen ovenfor er sann, vil påstanden passere.
La oss se det i aksjon!
3.1. er nært Med Dobbelt Verdier
La oss si at vi har et nummer lagret i en dobbel variabel kalt faktiske. Og vi vil teste om faktiske er nær 1 +/- 0,5.
Det er:
1 - 0,5 <= faktisk <= 1 + 0,5 0,5 <= faktisk <= 1,5
La oss nå lage en enhetstest ved hjelp av er nært matcher:
@Test offentlig ugyldighet gittADouble_whenCloseTo_thenCorrect () {double actual = 1.3; dobbel operand = 1; dobbel feil = 0,5; assertThat (faktisk, closeTo (operand, feil)); }
Ettersom 1,3 er mellom 0,5 og 1,5, vil testen bestå. På samme måte kan vi teste det negative scenariet:
@Test offentlig ugyldighet gittADouble_whenNotCloseTo_thenCorrect () {double actual = 1.6; dobbel operand = 1; dobbel feil = 0,5; assertThat (faktisk, ikke (closeTo (operand, feil))); }
La oss nå se på en lignende situasjon med en annen type variabler.
3.2. er nært Med BigDecimal Verdier
er nært er overbelastet og kan brukes samme som med doble verdier, men med BigDecimal gjenstander:
@Test offentlig ugyldig gittABigDecimal_whenCloseTo_thenCorrect () {BigDecimal faktisk = ny BigDecimal ("1.0003"); BigDecimal operand = ny BigDecimal ("1"); BigDecimal feil = ny BigDecimal ("0.0005"); assertThat (faktisk, er (closeTo (operand, feil))); } @Test offentlig ugyldig gittABigDecimal_whenNotCloseTo_thenCorrect () {BigDecimal faktisk = ny BigDecimal ("1.0006"); BigDecimal operand = ny BigDecimal ("1"); BigDecimal feil = ny BigDecimal ("0.0005"); assertThat (faktisk, er (ikke (closeTo (operand, feil)))); }
Vær oppmerksom på at de er matcher dekorerer bare andre matchere uten å legge til ekstra logikk. Det gjør bare hele påstanden mer lesbar.
Det handler om det for nærhetsspillere. Deretter tar vi en titt på ordrematchere.
4. Bestill matchere
Som navnet deres sier, disse matcherne hjelper med påstander om bestillingen.
Det er fem av dem:
- sammenlignerEqualTo
- større enn
- større enn eller lik
- mindre enn
- lessThanOrEqualTo
De er ganske mye selvforklarende, men la oss se noen eksempler.
4.1. Bestill matchere med Heltall Values
Det vanligste scenariet ville være bruker disse matcherne med tall.
Så la oss fortsette og lage noen tester:
@Test offentlig ugyldig gitt5_whenComparesEqualTo5_thenCorrect () {Heltall fem = 5; assertThat (fem, sammenligner EqualTo (fem)); } @Test offentlig ugyldig gitt5_whenNotComparesEqualTo7_thenCorrect () {Heltall sju = 7; Heltall fem = 5; hevder at (fem, ikke (sammenligner EqualTo (sju))); } @Test offentlig ugyldig gitt7_whenGreaterThan5_thenCorrect () {Heltall sju = 7; Heltall fem = 5; hevder at (syv, er (større enn (fem))); } @Test offentlig ugyldig gitt7_whenGreaterThanOrEqualTo5_thenCorrect () {Heltall sju = 7; Heltall fem = 5; assertThat (syv, er (greaterThanOrEqualTo (fem))); } @Test offentlig ugyldig gitt5_whenGreaterThanOrEqualTo5_thenCorrect () {Heltall fem = 5; assertThat (fem, er (greaterThanOrEqualTo (fem))); } @Test offentlig ugyldig given3_whenLessThan5_thenCorrect () {Heltall tre = 3; Heltall fem = 5; hevder at (tre, er (mindre enn (fem))); } @Test offentlig ugyldighet gitt3_whenLessThanOrEqualTo5_thenCorrect () {Heltall tre = 3; Heltall fem = 5; assertThat (tre, er (lessThanOrEqualTo (fem))); } @Test offentlig ugyldig gitt5_whenLessThanOrEqualTo5_thenCorrect () {Heltall fem = 5; assertThat (fem, er (lessThanOrEqualTo (fem))); }
Fornuftig, ikke sant? Vær oppmerksom på hvor enkelt det er å forstå hva predikatene hevder.
4.2. Bestill matchere med String Verdier
Selv om sammenligning av tall gir full mening, er det mange ganger nyttig å sammenligne andre typer elementer. Derfor ordrematchere kan brukes på alle klasser som implementerer Sammenlignelig grensesnitt.
La oss se noen eksempler med Strenger:
@Test offentlig ugyldighet gittBenjamin_whenGreaterThanAmanda_thenCorrect () {String amanda = "Amanda"; String benjamin = "Benjamin"; hevder at (Benjamin, er (greaterThan (amanda))); } @Test offentlig ugyldighet givenAmanda_whenLessThanBenajmin_thenCorrect () {String amanda = "Amanda"; String benjamin = "Benjamin"; hevder at (amanda, is (lessThan (benjamin))); }
String implementerer alfabetisk rekkefølge i sammenligne med metoden fra Sammenlignelig grensesnitt.
Så det er fornuftig at ordet "Amanda" kommer foran ordet "Benjamin".
4.3. Bestill matchere med LocalDate Verdier
Samme som med Strenger, kan vi sammenligne datoer. La oss ta en titt på de samme eksemplene vi opprettet ovenfor, men bruker LocalDate gjenstander:
@Test offentlig ugyldig givenToday_whenGreaterThanYesterday_thenCorrect () {LocalDate i dag = LocalDate.now (); LocalDate i går = i dag.minusDays (1); assertThat (i dag, er (greaterThan (igår))); } @Test offentlig ugyldig givenToday_whenLessThanTomorrow_thenCorrect () {LocalDate i dag = LocalDate.now (); LocalDate i morgen = i dag.plusDays (1); assertThat (i dag, er (lessThan (i morgen))); }
Det er veldig hyggelig å se at uttalelsen assertThat (i dag, er (lessThan (i morgen))) er nær vanlig engelsk.
4.4. Bestill matchere med tilpasset klassees
Så hvorfor ikke lage vår egen klasse og implementere Sammenlignelig? Den veien, vi kan utnytte ordrematchere som skal brukes med tilpassede ordreregler.
La oss starte med å lage en Person bønne:
offentlig klasse Person {Strengnavn; int alder; // standard konstruktør, getters og setters}
La oss nå implementere Sammenlignelig:
offentlig klasse Person implementerer sammenlignbar {// ... @Override public int CompareTo (Person o) {if (this.age == o.getAge ()) return 0; hvis (dette.alderen> o.getAge ()) returnerer 1; annet retur -1; }}
Våre sammenligne med implementering sammenligner to personer etter alder. La oss nå lage et par nye tester:
@Test offentlig ugyldighet gittAmanda_whenOlderThanBenjamin_thenCorrect () {Person amanda = ny person ("Amanda", 20); Person benjamin = ny person ("Benjamin", 18); hevder at (amanda, er (greaterThan (benjamin))); } @Test offentlig ugyldighet gittBenjamin_whenYoungerThanAmanda_thenCorrect () {Person amanda = ny person ("Amanda", 20); Person benjamin = ny person ("Benjamin", 18); hevder at (benjamin, er (lessThan (amanda))); }
Matchere vil nå jobbe basert på vår sammenligne med logikk.
5. NaN Matcher
Hamcrest sørger for en ekstra tallmatcher for å definere om et tall faktisk er, ikke et tall:
@Test offentlig ugyldighet gittNaN_whenIsNotANumber_thenCorrect () {dobbelt null = 0d; assertThat (null / null, er (notANumber ())); }
6. Konklusjoner
Som du kan se, tallmatchere er veldig nyttige for å forenkle vanlige påstander.
Dessuten er Hamcrest-matchere generelt selvforklarende og lett å lese.
Alt dette, pluss muligheten til å kombinere matchere med tilpasset sammenligningslogikk, gjør dem til et kraftig verktøy for de fleste prosjekter der ute.
Den fulle implementeringen av eksemplene fra denne artikkelen finner du på GitHub.