Brug af Hamcrest Number Matchers

1. Oversigt

Hamcrest leverer statiske matchere, der hjælper med at gøre enhedstest påstande enklere og mere læselige. Du kan komme i gang med at udforske nogle af de tilgængelige matchere her.

I denne artikel dykker vi dybere ned i de nummerrelaterede matchere.

2. Opsætning

For at få Hamcrest skal vi bare tilføje følgende Maven-afhængighed til vores pom.xml:

 org.hamcrest java-hamcrest 2.0.0.0 

Den seneste Hamcrest-version kan findes på Maven Central.

3. Nærhedsmatchere

Det første sæt matchere, som vi skal se på, er dem der Kontroller, om noget element er tæt på en værdi +/- en fejl.

Mere formelt:

værdi - fejl <= element <= værdi + fejl

Hvis sammenligningen ovenfor er sand, vil påstanden bestå.

Lad os se det i aktion!

3.1. erLuk Med Dobbelt Værdier

Lad os sige, at vi har et nummer gemt i en dobbelt variabel kaldet faktiske. Og vi vil teste, om faktiske er tæt på 1 +/- 0,5.

Det er:

1 - 0,5 <= faktisk <= 1 + 0,5 0,5 <= faktisk <= 1,5

Lad os nu oprette en enhedstest ved hjælp af erLuk matcher:

@Test offentligt ugyldigt givetADouble_whenCloseTo_thenCorrect () {double actual = 1.3; dobbelt operand = 1; dobbelt fejl = 0,5; assertThat (faktisk, closeTo (operand, fejl)); }

Da 1,3 er mellem 0,5 og 1,5, vil testen bestå. På samme måde kan vi teste det negative scenario:

@Test offentligt ugyldigt givetADouble_whenNotCloseTo_thenCorrect () {dobbelt faktisk = 1,6; dobbelt operand = 1; dobbelt fejl = 0,5; assertThat (faktisk, ikke (closeTo (operand, fejl))); }

Lad os nu se på en lignende situation med en anden type variabler.

3.2. erLuk Med BigDecimal Værdier

erLuk er overbelastet og kan bruges på samme måde som med dobbeltværdier, men med BigDecimal genstande:

@Test offentligt ugyldigt givetABigDecimal_whenCloseTo_thenCorrect () {BigDecimal faktisk = ny BigDecimal ("1.0003"); BigDecimal operand = ny BigDecimal ("1"); BigDecimal fejl = ny BigDecimal ("0.0005"); assertThat (faktisk, er (closeTo (operand, fejl))); } @Test offentlig ugyldighed givetABigDecimal_whenNotCloseTo_thenCorrect () {BigDecimal faktisk = ny BigDecimal ("1.0006"); BigDecimal operand = ny BigDecimal ("1"); BigDecimal fejl = ny BigDecimal ("0.0005"); assertThat (faktisk, er (ikke (closeTo (operand, fejl)))); }

Bemærk, at det er matcher dekorerer kun andre matchere uden at tilføje ekstra logik. Det gør bare hele påstanden mere læselig.

Det handler om det for nærhedsmatchere. Dernæst ser vi på ordrematchere.

4. Bestil matchere

Som deres navn siger, disse matchere hjælper med at komme med påstande om ordren.

Der er fem af dem:

  • sammenlignerEqualTo
  • bedre end
  • greaterThanOrEqualTo
  • Mindre end
  • lessThanOrEqualTo

De er stort set selvforklarende, men lad os se nogle eksempler.

4.1. Bestil matchere med Heltal Values

Det mest almindelige scenario ville være ved hjælp af disse matchere med tal.

Så lad os gå videre og oprette nogle tests:

@ Test offentligt ugyldigt given5_whenComparesEqualTo5_thenCorrect () {Heltal fem = 5; assertThat (fem, sammenligner EqualTo (fem)); } @Test offentligt ugyldigt givet5_whenNotComparesEqualTo7_thenCorrect () {Heltal syv = 7; Heltal fem = 5; hævder, at (fem, ikke (sammenligner EqualTo (syv))); } @Test offentligt ugyldigt given7_whenGreaterThan5_thenCorrect () {Heltal syv = 7; Heltal fem = 5; hævder, at (syv, er (størreTan (fem))); } @Test offentligt ugyldigt givet7_whenGreaterThanOrEqualTo5_thenCorrect () {Heltal syv = 7; Heltal fem = 5; hævder, at (syv er (størreTanOrEqualTo (fem))); } @ Test offentligt ugyldigt givet5_whenGreaterThanOrEqualTo5_thenCorrect () {Heltal fem = 5; hævder, at (fem, er (størreThanOrEqualTo (fem))); } @Test offentligt ugyldigt given3_whenLessThan5_thenCorrect () {Heltal tre = 3; Heltal fem = 5; hævder, at (tre, er (lessThan (fem))); } @Test offentlig ugyldighed given3_whenLessThanOrEqualTo5_thenCorrect () {Heltal tre = 3; Heltal fem = 5; hævder, at (tre, er (lessThanOrEqualTo (fem))); } @Test offentlig ugyldighed given5_whenLessThanOrEqualTo5_thenCorrect () {Heltal fem = 5; hævder, at (fem, er (lessThanOrEqualTo (fem))); }

Det giver mening, ikke? Vær opmærksom på, hvor enkelt det er at forstå, hvad prædikaterne hævder.

4.2. Bestil matchere med Snor Værdier

Selvom sammenligning af tal giver fuld mening, er det mange gange nyttigt at sammenligne andre typer elementer. Derfor ordrematchere kan anvendes på enhver klasse, der implementerer Sammenlignelig interface.

Lad os se nogle eksempler med Strenge:

@Test offentligt ugyldigt givetBenjamin_whenGreaterThanAmanda_thenCorrect () {String amanda = "Amanda"; String benjamin = "Benjamin"; hævder, at (benjamin, er (størreThan (amanda))); } @Test offentlig ugyldighed givenAmanda_whenLessThanBenajmin_thenCorrect () {String amanda = "Amanda"; String benjamin = "Benjamin"; hævder, at (amanda, er (lessThan (benjamin))); }

Snor implementerer alfabetisk rækkefølge i sammenligne med metode fra Sammenlignelig interface.

Så det giver mening, at ordet "Amanda" kommer foran ordet "Benjamin".

4.3. Bestil matchere med LocalDate Værdier

Samme som med Strenge, vi kan sammenligne datoer. Lad os se på de samme eksempler, som vi oprettede ovenfor, men bruger LocalDate genstande:

@Test offentlig ugyldighed givenToday_whenGreaterThanYesterday_thenCorrect () {LocalDate i dag = LocalDate.now (); LocalDate i går = i dag.minusDays (1); hævder, at (i dag er (greaterThan (i går))); } @Test offentlig ugyldighed givenToday_whenLessThanTomorrow_thenCorrect () {LocalDate i dag = LocalDate.now (); LocalDate i morgen = i dag.plusDays (1); assertThat (i dag er (lessThan (i morgen))); }

Det er meget rart at se, at udsagnet assertThat (i dag er (lessThan (i morgen))) er tæt på almindelig engelsk.

4.4. Bestil matchere med tilpasset klassees

Så hvorfor ikke oprette vores egen klasse og implementere Sammenlignelig? Den vej, vi kan udnytte ordrematchere til brug med tilpassede ordreregler.

Lad os starte med at oprette en Person bønne:

offentlig klasse Person {String name; int alder // standard konstruktør, getters og setter}

Lad os nu implementere Sammenlignelig:

public class Person implementer Comparable {// ... @Override public int compareTo (Person o) {if (this.age == o.getAge ()) return 0; hvis (this.age> o.getAge ()) returnerer 1; ellers returnerer -1; }}

Vores sammenligne med implementering sammenligner to personer efter deres alder. Lad os nu oprette et par nye tests:

@Test offentligt ugyldigt givetAmanda_whenOlderThanBenjamin_thenCorrect () {Person amanda = ny person ("Amanda", 20); Person benjamin = ny person ("Benjamin", 18); hævder, at (amanda, er (greaterThan (benjamin))); } @Test offentligt ugyldigt givetBenjamin_whenYoungerThanAmanda_thenCorrect () {Person amanda = ny person ("Amanda", 20); Person benjamin = ny person ("Benjamin", 18); hævder, at (benjamin, er (mindreThan (amanda))); }

Matchere vil nu arbejde baseret på vores sammenligne med logik.

5. NaN Matcher

Hamcrest giver en ekstra nummertilpasning til at definere, om et tal faktisk er, ikke et tal:

@Test offentlig ugyldighed givenNaN_whenIsNotANumber_thenCorrect () {dobbelt nul = 0d; assertThat (nul / nul, er (notANumber ())); }

6. Konklusioner

Som du kan se, antal matchere er meget nyttige til at forenkle almindelige påstande.

Hvad mere er, Hamcrest-matchere generelt er selvforklarende og let at læse.

Alt dette plus muligheden for at kombinere matchere med tilpasset sammenligningslogik gør dem til et kraftfuldt værktøj til de fleste projekter derude.

Den fulde implementering af eksemplerne fra denne artikel kan findes på GitHub.


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