Hamcrest Number Matchers gebruiken

1. Overzicht

Hamcrest biedt statische matchers om beweringen van unit-tests eenvoudiger en leesbaarder te maken. Je kunt hier beginnen met het verkennen van enkele van de beschikbare matchers.

In dit artikel gaan we dieper in op de nummer-gerelateerde matchers.

2. Installatie

Om Hamcrest te krijgen, hoeven we alleen de volgende Maven-afhankelijkheid toe te voegen aan onze pom.xml:

 org.hamcrest java-hamcrest 2.0.0.0 

De nieuwste Hamcrest-versie is te vinden op Maven Central.

3. Nabijheidsmatchers

De eerste set matchers die we gaan bekijken, zijn degenen die controleer of een element dichtbij een waarde +/- een fout ligt.

Meer formeel:

waarde - fout <= element <= waarde + fout

Als de bovenstaande vergelijking waar is, zal de bewering slagen.

Laten we het in actie zien!

3.1. is dichtbij Met Dubbele Waarden

Laten we zeggen dat we een nummer hebben opgeslagen in een dubbele variabele genaamd feitelijk. En we willen testen of feitelijk ligt dicht bij 1 +/- 0,5.

Dat is:

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

Laten we nu een unit-test maken met is dichtbij matcher:

@Test openbare ongeldig gegevenADouble_whenCloseTo_thenCorrect () {dubbele werkelijke = 1.3; dubbele operand = 1; dubbele fout = 0,5; assertThat (feitelijk, closeTo (operand, fout)); }

Aangezien 1,3 tussen 0,5 en 1,5 ligt, zal de test slagen. Op dezelfde manier kunnen we het negatieve scenario testen:

@Test openbare ongeldig gegevenADouble_whenNotCloseTo_thenCorrect () {dubbele werkelijke = 1.6; dubbele operand = 1; dubbele fout = 0,5; assertThat (feitelijk, niet (closeTo (operand, fout))); }

Laten we nu eens kijken naar een vergelijkbare situatie met een ander type variabelen.

3.2. is dichtbij Met BigDecimal Waarden

is dichtbij is overbelast en kan hetzelfde worden gebruikt als bij dubbele waarden, maar met BigDecimal voorwerpen:

@Test openbare ongeldig gegevenABigDecimal_whenCloseTo_thenCorrect () {BigDecimal actual = nieuw BigDecimal ("1.0003"); BigDecimal operand = nieuwe BigDecimal ("1"); BigDecimal-fout = nieuwe BigDecimal ("0.0005"); assertThat (actual, is (closeTo (operand, error))); } @Test openbare ongeldig gegevenABigDecimal_whenNotCloseTo_thenCorrect () {BigDecimal actual = nieuw BigDecimal ("1.0006"); BigDecimal operand = nieuwe BigDecimal ("1"); BigDecimal-fout = nieuwe BigDecimal ("0.0005"); assertThat (actual, is (not (closeTo (operand, error)))); }

Houd er rekening mee dat de is matcher siert alleen andere matchers zonder extra logica toe te voegen. Het maakt de hele bewering alleen maar leesbaarder.

Dat is het ongeveer voor nabijheidsmatchers. Vervolgens kijken we naar ordermatchers.

4. Bestel Matchers

Zoals hun naam zegt, deze matchers helpen bij het maken van beweringen over de bestelling.

Er zijn er vijf:

  • comparesEqualTo
  • groter dan
  • groter dan of gelijk aan
  • minder dan
  • minder dan of gelijk aan

Ze spreken voor zich, maar laten we eens kijken naar enkele voorbeelden.

4.1. Matchers bestellen met Geheel getal Values

Het meest voorkomende scenario zou zijn met behulp van deze matchers met getallen.

Dus laten we doorgaan en enkele tests maken:

@Test openbare ongeldig gegeven5_whenComparesEqualTo5_thenCorrect () {Integer vijf = 5; assertThat (five, comparesEqualTo (five)); } @Test openbare ongeldig gegeven5_whenNotComparesEqualTo7_thenCorrect () {Geheel getal zeven = 7; Geheel getal vijf = 5; assertThat (vijf, niet (vergelijktEqualTo (zeven))); } @Test openbare ongeldig gegeven7_whenGreaterThan5_thenCorrect () {Geheel getal zeven = 7; Geheel getal vijf = 5; assertThat (zeven, is (groter dan (vijf))); } @Test openbare ongeldig gegeven7_whenGreaterThanOrEqualTo5_thenCorrect () {Geheel getal zeven = 7; Geheel getal vijf = 5; assertThat (zeven, is (groterThanOrEqualTo (vijf))); } @Test openbare ongeldig gegeven5_whenGreaterThanOrEqualTo5_thenCorrect () {Integer vijf = 5; assertThat (vijf, is (groterThanOrEqualTo (vijf))); } @Test openbare ongeldige gegeven3_whenLessThan5_thenCorrect () {Geheel getal drie = 3; Geheel getal vijf = 5; assertThat (three, is (lessThan (five))); } @Test openbare ongeldig gegeven3_whenLessThanOrEqualTo5_thenCorrect () {Geheel getal drie = 3; Geheel getal vijf = 5; assertThat (three, is (lessThanOrEqualTo (five))); } @Test openbare ongeldig gegeven5_whenLessThanOrEqualTo5_thenCorrect () {Integer vijf = 5; assertThat (vijf, is (lessThanOrEqualTo (five))); }

Klopt toch? Merk op hoe eenvoudig het is om te begrijpen wat de predikaten beweren.

4.2. Matchers bestellen met Draad Waarden

Hoewel het vergelijken van getallen volkomen logisch is, is het vaak handig om andere soorten elementen te vergelijken. Daarom order matchers kunnen worden toegepast op elke klasse die de Vergelijkbaar koppel.

Laten we een paar voorbeelden bekijken met Snaren:

@Test openbare ongeldig gegevenBenjamin_whenGreaterThanAmanda_thenCorrect () {String amanda = "Amanda"; String benjamin = "Benjamin"; assertThat (benjamin, is (groter dan (amanda))); } @Test openbare leegte gegevenAmanda_whenLessThanBenajmin_thenCorrect () {String amanda = "Amanda"; String benjamin = "Benjamin"; assertThat (amanda, is (lessThan (benjamin))); }

Draad implementeert alfabetische volgorde in vergelijk met methode van de Vergelijkbaar koppel.

Het is dus logisch dat het woord "Amanda" voor het woord "Benjamin" komt.

4.3. Matchers bestellen met LocalDate Waarden

Hetzelfde als bij Snarenkunnen we datums vergelijken. Laten we eens kijken naar dezelfde voorbeelden die we hierboven hebben gemaakt, maar met LocalDate voorwerpen:

@Test openbare ongeldig gegevenToday_whenGreaterThanYesterday_thenCorrect () {LocalDate vandaag = LocalDate.now (); LocalDate gisteren = vandaag.minusDays (1); assertThat (vandaag, is (groter dan (gisteren))); } @Test openbare ongeldig gegevenToday_whenLessThanTomorrow_thenCorrect () {LocalDate vandaag = LocalDate.now (); LocalDate morgen = vandaag.plusDays (1); assertThat (vandaag, is (lessThan (morgen))); }

Het is erg leuk om te zien dat de verklaring assertThat (vandaag, is (lessThan (morgen))) ligt dicht bij normaal Engels.

4.4. Bestel Matchers met Custom Classes

Dus waarom zou u niet onze eigen klasse creëren en implementeren Vergelijkbaar? Op die manier we kunnen ordermatchers gebruiken om te worden gebruikt met aangepaste orderregels.

Laten we beginnen met het maken van een Persoon Boon:

openbare klasse Persoon {Stringnaam; int leeftijd; // standaard constructor, getters en setters}

Laten we nu implementeren Vergelijkbaar:

public class Person implementeert Vergelijkbaar {// ... @Override public int CompareTo (Person o) {if (this.age == o.getAge ()) return 0; if (this.age> o.getAge ()) retourneer 1; anders retourneert -1; }}

Onze vergelijk met implementatie vergelijkt twee mensen op basis van hun leeftijd. Laten we nu een paar nieuwe tests maken:

@Test openbare ongeldig gegevenAmanda_whenOlderThanBenjamin_thenCorrect () {Persoon amanda = nieuwe persoon ("Amanda", 20); Persoon benjamin = nieuwe persoon ("Benjamin", 18); assertThat (amanda, is (groter dan (benjamin))); } @Test openbare leegte gegevenBenjamin_whenYoungerThanAmanda_thenCorrect () {Persoon amanda = nieuwe persoon ("Amanda", 20); Persoon benjamin = nieuwe persoon ("Benjamin", 18); assertThat (benjamin, is (lessThan (amanda))); }

Matchers werken nu op basis van ons vergelijk met logica.

5. NaN Matcher

Hamcrest biedt een extra nummer matcher om te bepalen of een nummer werkelijk is, geen nummer:

@Test openbare ongeldige gegevenNaN_whenIsNotANumber_thenCorrect () {dubbele nul = 0d; assertThat (nul / nul, is (notANumber ())); }

6. Conclusies

Zoals je kunt zien, nummerovereenkomsten zijn erg handig om veelvoorkomende beweringen te vereenvoudigen.

Wat meer is, zijn Hamcrest-matchers in het algemeen spreekt voor zich en is gemakkelijk te lezen.

Dit alles, plus de mogelijkheid om matchers te combineren met aangepaste vergelijkingslogica, maakt ze tot een krachtig hulpmiddel voor de meeste projecten die er zijn.

De volledige implementatie van de voorbeelden uit dit artikel is te vinden op GitHub.