Testen met Google Truth

1. Overzicht

Waarheid is een een vloeiend en flexibel open-source testraamwerk dat is ontworpen om testverklaringen en foutmeldingen leesbaarder te maken.

In dit artikel zullen we de belangrijkste kenmerken van het Waarheid framework en implementeer voorbeelden om de mogelijkheden ervan te demonstreren.

2. Maven afhankelijkheden

Eerst moeten we de waarheid en waarheid-java8-extensie naar onze pom.xml:

 com.google.truth truth 0.32 com.google.truth.extensions truth-java8-extension 0.32 test 

U kunt de nieuwste versies van de waarheid en de waarheid-java8-extensie vinden op Maven Central.

3. Inleiding

Waarheid stelt ons in staat om leesbare beweringen en foutmeldingen te schrijven voor verschillende klassen:

  • Standaard Java - primitieven, arrays, strings, objecten, verzamelingen, throwables, klassen, etc.
  • Java 8Optioneel en Stroom gevallen
  • GuaveOptioneel, Multimap, Multiset, en Tafel voorwerpen
  • Aangepaste typen - door de extensie Onderwerpen klasse, zoals we later zullen zien

Door het Waarheid en Waarheid 8 klassen, biedt de bibliotheek hulpprogramma-methoden voor het schrijven van beweringen die werken op een onderwerpen, dat is de waarde of het object dat wordt getest.

Zodra het onderwerp bekend is, Waarheid kan tijdens het compileren redeneren over welke proposities bekend zijn voor dat onderwerp. Hierdoor kan het wrappers rond onze waarde retourneren die propositiemethoden specifiek voor dat specifieke onderwerp verklaren.

Als u bijvoorbeeld op een lijst staat, Waarheid geeft een IterableSubject instantie die methoden zoals bevat () en bevatAnyOf (), onder andere. Bij het claimen op een Kaart, het retourneert een MapSubject dat verklaart methoden zoals bevatEntry () en bevatKey ().

4. Aan de slag

Laten we eerst importeren om te beginnen met het schrijven van beweringen Waarheid'S toegangspunten:

importeer statische com.google.common.truth.Truth. *; importeer statische com.google.common.truth.Truth8. *;

Laten we nu een eenvoudige les schrijven die we zullen gebruiken in een paar van de voorbeelden die volgen:

openbare klasse Gebruiker {private String name = "John Doe"; private List emails = Arrays.asList ("[email protected]", "[email protected]"); openbare boolean is gelijk aan (Object obj) {if (obj == null || getClass ()! = obj.getClass ()) {return false; } Gebruiker other = (User) obj; retourneer Objects.equals (this.name, other.name); } // standaard constructeurs, getters en setters}

Let op de gewoonte is gelijk aan () methode, waarin we stellen dat twee Gebruiker objecten zijn gelijk als hun namen zijn.

5. Standaard Java-beweringen

In dit gedeelte zullen we gedetailleerde voorbeelden zien van het schrijven van testverklaringen voor standaard Java-typen.

5.1. Voorwerp Beweringen

Waarheid biedt de Onderwerpen wrapper voor het uitvoeren van beweringen op objecten. Onderwerpen is ook de ouder van alle andere wrappers in de bibliotheek en declareert methoden om te bepalen of een Voorwerp, in ons geval een Gebruiker, is gelijk aan een ander object:

@Test public void whenComparingUsers_thenEqual () {User aUser = nieuwe gebruiker ("John Doe"); Gebruiker anotherUser = nieuwe gebruiker ("Jan Jansen"); assertThat (aUser) .isEqualTo (anotherUser); }

of als het gelijk is aan een bepaald object in een lijst:

@ Test openbare ongeldig whenComparingUser_thenInList () {User aUser = nieuwe gebruiker (); assertThat (aUser) .isIn (Arrays.asList (1, 3, aUser, null)); }

of als het niet:

@Test openbare leegte whenComparingUser_thenNotInList () {// ... assertThat (aUser) .isNotIn (Arrays.asList (1, 3, "Three")); }

als het null is of niet:

@Test openbare ongeldig whenComparingUser_thenIsNull () {User aUser = null; assertThat (aUser) .isNull (); } @Test openbare leegte whenComparingUser_thenNotNull () {Gebruiker aUser = nieuwe gebruiker (); assertThat (aUser) .isNotNull (); }

of als het een instantie van een bepaalde klasse is:

@Test openbare leegte whenComparingUser_thenInstanceOf () {// ... assertThat (aUser) .isInstanceOf (User.class); }

Er zijn andere beweringsmethoden in het Onderwerpen klasse. Raadpleeg het Onderwerpen documentatie.

In de volgende secties, we gaan ons concentreren op de meest relevante methoden voor elk specifiek typeWaarheid ondersteunt. Houd er echter rekening mee dat alle methoden in het Onderwerpen klasse kan ook worden toegepast.

5.2. Geheel getal, Vlotter, en Dubbele Beweringen

Geheel getal, Vlotter, en Dubbele gevallen kunnen worden vergeleken voor gelijkheid:

@Test openbare leegte whenComparingInteger_thenEqual () {int anInt = 10; assertThat (anInt) .isEqualTo (10); }

als ze groter zijn:

@Test openbare leegte whenComparingFloat_thenIsBigger () {float aFloat = 10.0f; assertThat (aFloat) .isGreaterThan (1.0f); }

of kleiner:

@ Test openbare ongeldig whenComparingDouble_thenIsSmaller () {double aDouble = 10.0f; assertThat (aDouble) .isLessThan (20.0); }

Verder, Float en Dubbele instanties kunnen ook worden gecontroleerd om te zien of ze binnen een verwachte nauwkeurigheid vallen of niet:

@Test openbare ongeldig whenComparingDouble_thenWithinPrecision () {double aDouble = 22.18; assertThat (aDouble) .isWithin (2) .of (23d); } @Test openbare leegte whenComparingFloat_thenNotWithinPrecision () {float aFloat = 23.04f; assertThat (aFloat) .isNotWithin (1.3f) .of (100f); }

5.3. BigDecimal Beweringen

Naast de gebruikelijke beweringen, kan dit type worden vergeleken zonder de schaal ervan te negeren:

@Test openbare leegte whenComparingBigDecimal_thenEqualIgnoringScale () {BigDecimal aBigDecimal = BigDecimal.valueOf (1000, 3); assertThat (aBigDecimal) .isEqualToIgnoringScale (nieuwe BigDecimal (1.0)); }

5.4. Boolean Beweringen

Er zijn slechts twee relevante methoden beschikbaar, is waar() en is fout():

@Test openbare leegte whenCheckingBoolean_thenTrue () {boolean aBoolean = true; assertThat (aBoolean) .isTrue (); }

5.5. Draad Beweringen

We kunnen testen of a Draad begint met een bepaalde tekst:

@Test public void whenCheckingString_thenStartsWith () {String aString = "Dit is een string"; assertThat (aString) .startsWith ("This"); }

Daarnaast kunnen we controleren of de string een bepaalde string bevat, of deze eindigt met een verwachte waarde of leeg is. Testcases voor deze en andere methoden zijn beschikbaar in de broncode.

5.6. Array-beweringen

We kunnen het controleren Arrays om te zien of ze gelijk zijn aan andere arrays:

@Test public void whenComparingArrays_thenEqual () {String [] firstArrayOfStrings = {"een", "twee", "drie"}; String [] secondArrayOfStrings = {"een", "twee", "drie"}; assertThat (firstArrayOfStrings) .isEqualTo (secondArrayOfStrings); }

of als ze leeg zijn:

@Test openbare leegte whenCheckingArray_thenEmpty () {Object [] anArray = {}; assertThat (anArray) .isEmpty (); }

5.7. Vergelijkbaar Beweringen

Naast het testen of een Vergelijkbaar groter of kleiner is dan een andere instantie, kunnen we controleren of ze ten minste een bepaalde waarde hebben:

@Test openbare ongeldig whenCheckingComparable_thenAtLeast () {Vergelijkbaar aComparable = 5; assertThat (aComparable) .isAtLeast (1); }

We kunnen ook testen of ze binnen een bepaald bereik vallen:

@Test openbare leegte whenCheckingComparable_thenInRange () {// ... assertThat (aComparable) .isIn (Range.closed (1, 10)); }

of in een bepaalde lijst:

@Test openbare leegte whenCheckingComparable_thenInList () {// ... assertThat (aComparable) .isIn (Arrays.asList (4, 5, 6)); }

We kunnen ook testen of er twee zijn Vergelijkbaar instanties zijn equivalent volgens de class's vergelijk met() methode.

Laten we eerst onze Gebruiker klasse om het Vergelijkbaar koppel:

public class Gebruiker implementeert Vergelijkbaar {// ... public int CompareTo (User o) {return this.getName (). CompareToIgnoreCase (o.getName ()); }}

Laten we nu beweren dat twee gebruikers met dezelfde naam equivalent zijn:

@Test openbare leegte whenComparingUsers_thenEquivalent () {Gebruiker aUser = nieuwe gebruiker (); aUser.setName ("John Doe"); Gebruiker anotherUser = nieuwe gebruiker (); anotherUser.setName ("john doe"); assertThat (aUser) .isEquivalentAccordingToCompareTo (anotherUser); }

5.8. Herhaalbaar Beweringen

Naast het beweren van de grootte van een Herhaalbaar of het nu leeg is of geen duplicaten heeft, de meest typische beweringen over een Herhaalbaar zijn dat het een element bevat:

@Test openbare leegte whenCheckingIterable_thenContains () {List aList = Arrays.asList (4, 5, 6); assertThat (aList) .contains (5); }

dat het enig element van een ander bevat Herhaalbaar:

@Test openbare leegte whenCheckingIterable_thenContainsAnyInList () {List aList = Arrays.asList (1, 2, 3); assertThat (aList) .containsAnyIn (Arrays.asList (1, 5, 10)); }

en dat het onderwerp dezelfde elementen heeft, in dezelfde volgorde, als een ander:

@Test openbare leegte whenCheckingIterable_thenContainsExactElements () {List aList = Arrays.asList ("10", "20", "30"); List anotherList = Arrays.asList ("10", "20", "30"); assertThat (aList) .containsExactlyElementsIn (anotherList) .inOrder (); }

en als het is besteld met behulp van een aangepaste comparator:

@Test openbare leegte gegevenComparator_whenCheckingIterable_thenOrdered () {Comparator aComparator = (a, b) -> nieuwe Float (a) .compareTo (nieuwe Float (b)); List aList = Arrays.asList ("1", "012", "0020", "100"); assertThat (aList) .isOrdered (aComparator); }

5.9. Kaart Beweringen

Naast het beweren dat a Kaart instantie is leeg of niet, of heeft een specifieke grootte; we kunnen controleren of het een specifiek item heeft:

@Test openbare leegte whenCheckingMap_thenContainsEntry () {Map aMap = nieuwe HashMap (); aMap.put ("één", 1L); assertThat (aMap) .containsEntry ("één", 1L); }

als het een specifieke sleutel heeft:

@Test openbare leegte whenCheckingMap_thenContainsKey () {// ... assertThat (kaart) .containsKey ("één"); }

of als het dezelfde vermeldingen heeft als een ander Kaart:

@Test openbare leegte whenCheckingMap_thenContainsEntries () {Map aMap = nieuwe HashMap (); aMap.put ("eerste", 1L); aMap.put ("tweede", 2.0); aMap.put ("derde", 3f); Map anotherMap = nieuwe HashMap (aMap); assertThat (aMap) .containsExactlyEntriesIn (anotherMap); }

5.10. Uitzondering Beweringen

Er zijn slechts twee belangrijke methoden voorzien Uitzondering voorwerpen.

We kunnen beweringen schrijven die zijn gericht op de oorzaak van de uitzondering:

@Test openbare leegte whenCheckingException_thenInstanceOf () {Uitzondering anException = nieuwe IllegalArgumentException (nieuwe NumberFormatException ()); assertThat (anException) .hasCauseThat () .isInstanceOf (NumberFormatException.class); }

of naar zijn bericht:

@Test public void whenCheckingException_thenCauseMessageIsKnown () {Uitzondering anException = nieuwe IllegalArgumentException ("Slechte waarde"); assertThat (anException) .hasMessageThat () .startsWith ("Bad"); }

5.11. Klasse Beweringen

Er is maar één belangrijke methode voor Klasse beweringen waarmee we kunnen testen of een klasse aan een andere kan worden toegewezen:

@Test openbare ongeldig whenCheckingClass_thenIsAssignable () {Class aClass = Double.class; assertThat (aClass) .isAssignableTo (Number.class); }

6. Java 8-beweringen

Optioneel en Stroom zijn de enige twee Java 8-typen die Waarheid ondersteunt.

6.1. Optioneel Beweringen

Er zijn drie belangrijke methoden om een Optioneel.

We kunnen testen of het een bepaalde waarde heeft:

@Test public void whenCheckingJavaOptional_thenHasValue () {Optioneel anOptional = Optioneel.of (1); assertThat (anOptional) .hasValue (1); }

als de waarde aanwezig is:

@Test public void whenCheckingJavaOptional_thenPresent () {Optioneel anOptional = Optioneel.of ("Baeldung"); assertThat (anOptional) .isPresent (); }

of als de waarde niet aanwezig is:

@Test openbare leegte whenCheckingJavaOptional_thenEmpty () {Optioneel anOptional = Optioneel.empty (); assertThat (anOptional) .isEmpty (); }

6.2. Stroom Beweringen

Beweringen voor een Stroom lijken erg op die voor een Herhaalbaar.

We kunnen bijvoorbeeld testen of een bepaald Stroom bevat alle objecten van een Herhaalbaar in dezelfde volgorde:

@Test openbare ongeldig whenCheckingStream_thenContainsInOrder () {Stream anStream = Stream.of (1, 2, 3); assertThat (anStream) .containsAllOf (1, 2, 3) .inOrder (); }

Voor meer voorbeelden verwijzen wij u naar het Herhaalbaar Beweringen sectie.

7. Guava-beweringen

In deze sectie zien we voorbeelden van beweringen voor de ondersteunde Guava-typen in Waarheid.

7.1. Optioneel Beweringen

Er zijn ook drie belangrijke beweringsmethoden voor een guave Optioneel. De hasValue () en is aanwezig() methoden gedragen zich precies zoals bij een Java 8 Optioneel.

Maar in plaats van is leeg() om te beweren dat een Optioneel is niet aanwezig, we gebruiken is afwezig():

@Test openbare leegte whenCheckingGuavaOptional_thenIsAbsent () {Optioneel anOptional = Optioneel.absent (); assertThat (anOptional) .isAbsent (); }

7.2. Multimap Beweringen

Multimap en standaard Kaart beweringen lijken erg op elkaar.

Een opmerkelijk verschil is dat we de meerdere waarden van een sleutel binnen een Multimap en beweringen doen over die waarden.

Hier is een voorbeeld dat test of de waarden van de "één" -toets een grootte van twee hebben:

@ Test openbare leegte whenCheckingGuavaMultimap_thenExpectedSize () {Multimap aMultimap = ArrayListMultimap.create (); aMultimap.put ("één", 1L); aMultimap.put ("één", 2.0); assertThat (aMultimap) .valuesForKey ("één") .hasSize (2); }

Voor meer voorbeelden verwijzen wij u naar het Kaart Beweringen sectie.

7.3. Multiset Beweringen

Beweringen voor Multiset objecten omvatten die voor een Herhaalbaar en een extra methode om te verifiëren of een sleutel een bepaald aantal keren voorkomt:

@Test openbare leegte whenCheckingGuavaMultiset_thenExpectedCount () {TreeMultiset aMultiset = TreeMultiset.create (); aMultiset.add ("baeldung", 10); assertThat (aMultiset) .hasCount ("baeldung", 10); }

7.4. Tafel Beweringen

Naast het controleren van de grootte of waar het leeg is, kunnen we een Tafel om te controleren of het een bepaalde toewijzing bevat voor een bepaalde rij en kolom:

@Test openbare leegte whenCheckingGuavaTable_thenContains () {Tabel aTable = TreeBasedTable.create (); aTable.put ("firstRow", "firstColumn", "baeldung"); assertThat (aTable) .contains ("firstRow", "firstColumn"); }

of als het een bepaalde cel bevat:

@Test openbare leegte whenCheckingGuavaTable_thenContainsCell () {Tabel aTable = getDummyGuavaTable (); assertThat (aTable) .containsCell ("firstRow", "firstColumn", "baeldung"); }

Verder kunnen we controleren of het een bepaalde rij, kolom of waarde bevat. Zie de broncode voor de relevante testcases.

8. Aangepaste foutberichten en labels

Als een bewering mislukt, Waarheid geeft zeer leesbare berichten weer die precies aangeven wat er mis is gegaan. Soms is het echter nodig om meer informatie aan die berichten toe te voegen om meer details te geven over wat er is gebeurd.

Waarheid stelt ons in staat om die foutmeldingen aan te passen:

@Test public void whenFailingAssertion_thenCustomMessage () {assertWithMessage ("TEST-985: Geheim gebruikersonderwerp was NIET null!") .That (nieuwe gebruiker ()) .isNull (); }

Na het uitvoeren van de test krijgen we de volgende output:

TEST-985: Onderwerp van geheime gebruiker was NIET null !: Het is niet waar dat <[email protected]> null is

We kunnen ook een aangepast label toevoegen dat in foutmeldingen voor ons onderwerp wordt weergegeven. Dit kan handig zijn als een object geen handige tekenreeksweergave heeft:

@Test public void whenFailingAssertion_thenMessagePrefix () {User aUser = nieuwe gebruiker (); assertThat (aUser) .named ("Gebruiker [% s]", aUser.getName ()) .isNull (); }

Als we de test uitvoeren, zien we de volgende uitvoer:

Het is niet waar dat gebruiker [John Doe] (<[e-mail beveiligd]>) null is

9. Uitbreidingen

Verlengend Waarheid betekent dat we ondersteuning voor aangepaste typen kunnen toevoegen. Om dit te doen, moeten we een klasse maken die:

  • breidt de Onderwerpen klasse of een van zijn subklassen
  • definieert een constructor die twee argumenten accepteert - a FailureStrategy en een exemplaar van ons aangepaste type
  • verklaart een veld van SubjectFactory type, welke Waarheid zal gebruiken om exemplaren van ons aangepaste onderwerp te maken
  • implementeert een statisch assertThat () methode die ons aangepaste type accepteert
  • stelt onze API voor testbevestiging bloot

Nu we weten hoe we moeten verlengen Waarheid, laten we een klasse maken die ondersteuning toevoegt voor objecten van het type Gebruiker:

openbare klasse UserSubject breidt ComparableSubject uit {privé UserSubject (FailureStrategy failureStrategy, User target) {super (failureStrategy, target); } private static final SubjectFactory USER_SUBJECT_FACTORY = nieuwe SubjectFactory () {openbaar UserSubject getSubject (FailureStrategy failureStrategy, User target) {return new UserSubject (failureStrategy, target); }}; openbare statische UserSubject assertThat (gebruiker gebruiker) {return Truth.assertAbout (USER_SUBJECT_FACTORY) .that (gebruiker); } public void hasName (String name) {if (! actual (). getName (). equals (name)) {fail ("has name", name); }} public void hasNameIgnoringCase (String naam) {if (! actual (). getName (). equalsIgnoreCase (naam)) {fail ("heeft naam negerend hoofdletter", naam); }} openbare IterableSubject e-mails () {retourneer Truth.assertThat (actual (). getEmails ()); }}

Nu kunnen we het bewerenThat () methode van ons aangepaste onderwerp en schrijf enkele tests:

@Test openbaar ongeldig whenCheckingUser_thenHasName () {User aUser = nieuwe gebruiker (); assertThat (aUser) .hasName ("John Doe"); } @Test openbare leegte whenCheckingUser_thenHasNameIgnoringCase () {// ... assertThat (aUser) .hasNameIgnoringCase ("john doe"); } @Test openbare leegte gegevenUser_whenCheckingEmails_thenExpectedSize () {// ... assertThat (aUser) .emails () .hasSize (2); }

10. Conclusie

In deze tutorial hebben we de mogelijkheden verkend Waarheid geeft ons meer leesbare tests en foutmeldingen.

We hebben de meest populaire assertiemethoden voor ondersteunde Java- en Guava-typen, aangepaste foutberichten en uitgebreide Waarheid met aangepaste onderwerpen.

Zoals altijd is de volledige broncode voor dit artikel te vinden op Github.


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