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.


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