Java >> Java Tutorial >  >> Tag >> assert

JUnit 5 Tutorial:Assertionen mit Hamcrest schreiben

Dieser Blogbeitrag beschreibt, wie wir Assertionen mit Hamcrest schreiben können. Nachdem wir diesen Blogbeitrag fertiggestellt haben, werden wir:

  • Kann die erforderlichen Abhängigkeiten mit Maven und Gradle erhalten.
  • Wissen, wie wir grundlegende Behauptungen mit Hamcrest schreiben können.
  • Verstehen Sie, wie wir mehrere Hamcrest-Matcher kombinieren können.
  • Kann die Fehlermeldung anpassen, die angezeigt wird, wenn eine Assertion fehlschlägt.

Fangen wir an.

Erforderliche Abhängigkeiten abrufen

Bevor wir Assertionen mit Hamcrest schreiben können, müssen wir sicherstellen, dass die hamcrest-library Abhängigkeit (Version 2.2) wird aus dem Klassenpfad gefunden.

Wenn wir Maven verwenden, müssen wir die hamcrest-library hinzufügen Abhängigkeit von test Umfang. Wir können dies tun, indem wir das folgende Snippet zu depencies hinzufügen Abschnitt unserer pom.xml Datei:

<dependency>
	<groupId>org.hamcrest</groupId>
	<artifactId>hamcrest-library</artifactId>
	<version>2.2</version>
	<scope>test</scope>
</dependency>

Wenn wir Gradle verwenden, müssen wir den hamcrest-library hinzufügen Abhängigkeit zum testImplementation Abhängigkeitskonfiguration. Wir können dies tun, indem wir das folgende Snippet zu unserem build.gradle hinzufügen Datei:

dependencies {
    testImplementation(
            'org.hamcrest:hamcrest-library:2.2'
    )
}

Nachdem wir sichergestellt haben, dass die hamcrest-library Abhängigkeit aus dem Klassenpfad gefunden wird, können wir Assertionen mit Hamcrest schreiben. Lassen Sie uns herausfinden, wie wir es tun können.

Behauptungen schreiben mit Hamcrest

Wenn Sie Hamcrest mit JUnit 4 verwendet haben, werden Sie sich wahrscheinlich daran erinnern, dass Sie den assertThat() verwenden mussten Methode des org.junit.Assert Klasse. Die JUnit 5-API hat jedoch keine Methode, die einen Hamcrest-Matcher als Methodenparameter verwendet. Das JUnit 5-Benutzerhandbuch erklärt diese Designentscheidung wie folgt:

Allerdings JUnit Jupiters org.junit.jupiter.api.Assertions Klasse stellt keinen assertThat() bereit Methode wie die in org.junit.Assert von JUnit 4 Klasse, die ein Hamcrest Matcher akzeptiert . Stattdessen werden Entwickler ermutigt, die integrierte Unterstützung für Matcher zu verwenden, die von Assertionsbibliotheken von Drittanbietern bereitgestellt werden.

Mit anderen Worten, wenn wir Hamcrest-Matcher verwenden möchten, müssen wir den assertThat() verwenden Methode des org.hamcrest.MatcherAssert Klasse. Diese Methode nimmt entweder zwei oder drei Methodenparameter, die im Folgenden beschrieben werden:

  1. Eine optionale Fehlermeldung, die angezeigt wird, wenn unsere Assertion fehlschlägt.
  2. Der tatsächliche Wert oder das Objekt.
  3. A Matcher Objekt, das den erwarteten Wert angibt. Wir können Matcher neu erstellen Objekte mit dem static Factory-Methoden, die von org.hamcrest.Matchers bereitgestellt werden Klasse.

Als nächstes schauen wir uns einige Beispiele an, die zeigen, wie wir Assertionen mit Hamcrest schreiben können. Beginnen wir damit herauszufinden, wie wir Zusicherungen für boolean schreiben können Werte.

Boolesche Werte bestätigen

Wenn wir überprüfen möchten, ob ein boolean Wert ist true , müssen wir unseren Hamcrest-Matcher erstellen, indem wir is() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

@DisplayName("Write assertions for booleans")
class BooleanAssertionTest {

    @Nested
    @DisplayName("When boolean is true")
    class WhenBooleanIsTrue {

        @Test
        @DisplayName("Should be true")
        void shouldBeTrue() {
            assertThat(true, is(true));
        }
    }
}

Wenn wir überprüfen wollen, ob ein boolean Wert ist false , müssen wir unseren Hamcrest-Matcher erstellen, indem wir is() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

@DisplayName("Write assertions for booleans")
class BooleanAssertionTest {

    @Nested
    @DisplayName("When boolean is false")
    class WhenBooleanIsFalse {

        @Test
        @DisplayName("Should be false")
        void shouldBeFalse() {
            assertThat(false, is(false));
        }
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir überprüfen können, ob ein Objekt null ist oder ist nicht null .

Behaupten, dass ein Objekt Null ist oder nicht Null ist

Wenn wir überprüfen möchten, ob ein Objekt null ist , müssen wir unseren Hamcrest-Matcher erstellen, indem wir nullValue() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;

@DisplayName("Writing assertions for objects")
class ObjectAssertionTest {

    @Nested
    @DisplayName("When object is null")
    class WhenObjectIsNull {

        @Test
        @DisplayName("Should be null")
        void shouldBeNull() {
            assertThat(null, nullValue());
        }
    }
}

Wenn wir überprüfen möchten, ob ein Objekt nicht null ist , müssen wir unseren Hamcrest-Matcher erstellen, indem wir notNullValue() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;

@DisplayName("Writing assertions for objects")
class ObjectAssertionTest {

    @Nested
    @DisplayName("When object is not null")
    class WhenObjectIsNotNotNull {

        @Test
        @DisplayName("Should not be null")
        void shouldNotBeNull() {
            assertThat(new Object(), notNullValue());
        }
    }
}

Als nächstes werden wir herausfinden, wie wir überprüfen können, ob zwei Objekte (oder Werte) gleich oder ungleich sind.

Behaupten, dass zwei Objekte oder Werte gleich sind

Wenn wir überprüfen möchten, ob der erwartete Wert (oder Objekt) gleich dem tatsächlichen Wert (oder Objekt) ist, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den equalTo() aufrufen Methode des Matchers Klasse. Zum Beispiel, wenn wir zwei Integer vergleichen möchten Objekten müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

@DisplayName("Writing assertions for objects")
class ObjectAssertionTest {

    @Nested
    @DisplayName("When two objects are equal")
    class WhenTwoObjectsAreEqual {

        @Nested
        @DisplayName("When objects are integers")
        class WhenObjectsAreIntegers {

            private final Integer ACTUAL = 9;
            private final Integer EXPECTED = 9;

            @Test
            @DisplayName("Should be equal")
            void shouldBeEqual() {
                assertThat(ACTUAL, equalTo(EXPECTED));
            }
        }
    }
}

Wenn wir überprüfen wollen, ob der erwartete Wert (oder Objekt) nicht gleich dem tatsächlichen Wert (oder Objekt) ist, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den not() aufrufen Methode des Matchers Klasse. Zum Beispiel, wenn wir zwei Integer vergleichen möchten Objekten müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.not;

@DisplayName("Writing assertions for objects")
class ObjectAssertionTest {

    @Nested
    @DisplayName("When two objects aren't equal")
    class WhenTwoObjectsAreNotEqual {

        @Nested
        @DisplayName("When objects are integers")
        class WhenObjectsAreIntegers {

            private final Integer ACTUAL = 9;
            private final Integer EXPECTED = 4;

            @Test
            @DisplayName("Should not be equal")
            void shouldNotBeEqual() {
                assertThat(ACTUAL, not(EXPECTED));
            }
        }
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir Zusicherungen für Objektreferenzen schreiben können.

Bestätigen von Objektreferenzen

Wenn wir sicherstellen wollen, dass zwei Objekte auf dasselbe Objekt verweisen, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den sameInstance() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.sameInstance;

@DisplayName("Writing assertions for objects")
class ObjectAssertionTest {

    @Nested
    @DisplayName("When two objects refer to the same object")
    class WhenTwoObjectsReferToSameObject {

        private final Object ACTUAL = new Object();
        private final Object EXPECTED = ACTUAL;

        @Test
        @DisplayName("Should refer to the same object")
        void shouldReferToSameObject() {
            assertThat(ACTUAL, sameInstance(EXPECTED));
        }
    }
}

Wenn wir sicherstellen wollen, dass zwei Objekte nicht auf dasselbe Objekt verweisen, müssen wir die durch sameInstance() angegebene Erwartung umkehren Methode mit not() Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.sameInstance;

@DisplayName("Writing assertions for objects")
class ObjectAssertionTest {

    @Nested
    @DisplayName("When two objects don't refer to the same object")
    class WhenTwoObjectsDoNotReferToSameObject {

        private final Object ACTUAL = new Object();
        private final Object EXPECTED = new Object();

        @Test
        @DisplayName("Should not refer to the same object")
        void shouldNotReferToSameObject() {
           assertThat(ACTUAL, not(sameInstance(EXPECTED)));
        }
    }
}

Als nächstes werden wir herausfinden, wie wir überprüfen können, ob zwei Arrays gleich sind.

Behauptung, dass zwei Arrays gleich sind

Wenn wir überprüfen möchten, ob zwei Arrays gleich sind, müssen wir unseren Hamcrest-Matcher erstellen, indem wir equalTo() aufrufen Methode des Matchers Klasse. Zum Beispiel, wenn wir überprüfen wollen, ob zwei int Arrays gleich sind, müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

@DisplayName("Write assertions for arrays")
class ArrayAssertionTest {

    @Nested
    @DisplayName("When arrays contain integers")
    class WhenArraysContainIntegers {

        final int[] ACTUAL = new int[]{2, 5, 7};
        final int[] EXPECTED = new int[]{2, 5, 7};

        @Test
        @DisplayName("Should contain the same integers")
        void shouldContainSameIntegers() {
            assertThat(ACTUAL, equalTo(EXPECTED));
        }
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir Zusicherungen für Listen schreiben können.

Listen behaupten

Wenn wir eine Assertion schreiben wollen, die verifiziert, dass die Größe einer Liste korrekt ist, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den hasSize() aufrufen Methode des Matchers Klasse. Wenn wir zum Beispiel überprüfen wollen, ob die Größe einer Liste 2 ist, müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we write assertions for elements")
    class WhenWeWriteAssertionsForElements {
        
        private Object first;
        private Object second;

        private List<Object> list;

        @BeforeEach
        void createAndInitializeList() {
            first = new Object();
            second = new Object();

            list = Arrays.asList(first, second);
        }

        @Test
        @DisplayName("Should contain two elements")
        void shouldContainTwoElements() {
            assertThat(list, hasSize(2));
        }
    }
}

Wenn wir überprüfen möchten, ob die Liste nur die erwarteten Elemente in der angegebenen Reihenfolge enthält, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den contains() aufrufen Methode des Matchers Klasse. Wenn wir beispielsweise überprüfen möchten, ob unsere Liste die richtigen Elemente in der angegebenen Reihenfolge enthält, müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we write assertions for elements")
    class WhenWeWriteAssertionsForElements {

        private Object first;
        private Object second;

        private List<Object> list;

        @BeforeEach
        void createAndInitializeList() {
            first = new Object();
            second = new Object();

            list = Arrays.asList(first, second);
        }

        @Test
        @DisplayName("Should contain the correct elements in the given order")
        void shouldContainCorrectElementsInGivenOrder() {
            assertThat(list, contains(first, second));
        }
    }
}

Wenn wir überprüfen möchten, dass die Liste nur die erwarteten Elemente in beliebiger Reihenfolge enthält, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den containsInAnyOrder() aufrufen Methode des Matchers Klasse. Wenn wir beispielsweise überprüfen möchten, ob unsere Liste die richtigen Elemente in beliebiger Reihenfolge enthält, müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we write assertions for elements")
    class WhenWeWriteAssertionsForElements {

        private Object first;
        private Object second;

        private List<Object> list;

        @BeforeEach
        void createAndInitializeList() {
            first = new Object();
            second = new Object();

            list = Arrays.asList(first, second);
        }

        @Test
        @DisplayName("Should contain the correct elements in any order")
        void shouldContainCorrectElementsInAnyOrder() {
            assertThat(list, containsInAnyOrder(second, first));
        }
    }
}

Wenn wir sicherstellen wollen, dass eine Liste das angegebene Element enthält, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den hasItem() aufrufen Methode des Matchers Klasse. Zum Beispiel, wenn wir überprüfen möchten, ob unsere Liste den Object enthält das ist im Feld namens first gespeichert , müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we write assertions for elements")
    class WhenWeWriteAssertionsForElements {

        private Object first;
        private Object second;

        private List<Object> list;

        @BeforeEach
        void createAndInitializeList() {
            first = new Object();
            second = new Object();

            list = Arrays.asList(first, second);
        }

        @Test
        @DisplayName("Should contain a correct element")
        void shouldContainCorrectElement() {
            assertThat(list, hasItem(first));
        }
    }
}

Wenn wir sicherstellen wollen, dass eine Liste kein Element enthält, müssen wir die durch hasItem() angegebene Erwartung umkehren Methode mit not() Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we write assertions for elements")
    class WhenWeWriteAssertionsForElements {

        private Object first;
        private Object second;

        private List<Object> list;

        @BeforeEach
        void createAndInitializeList() {
            first = new Object();
            second = new Object();

            list = Arrays.asList(first, second);
        }

        @Test
        @DisplayName("Should not contain an incorrect element")
        void shouldNotContainIncorrectElement() {
            assertThat(list, not(hasItem(new Object())));
        }
    }
}

Wenn wir überprüfen möchten, ob zwei Listen absolut gleich sind, müssen wir unseren Hamcrest-Matcher erstellen, indem wir equalTo() aufrufen Methode des Matchers Klasse. Zum Beispiel, wenn wir überprüfen wollen, ob zwei Integer Listen zutiefst gleich sind, müssen wir diese Behauptung verwenden:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we compare two lists")
    class WhenWeCompareTwoLists {

        private final List<Integer> ACTUAL = Arrays.asList(1, 2, 3);
        private final List<Integer> EXPECTED = Arrays.asList(1, 2, 3);

        @Test
        @DisplayName("Should contain the same elements")
        void shouldContainSameElements() {
            assertThat(ACTUAL, equalTo(EXPECTED));
        }
    }
}

Als nächstes werden wir herausfinden, wie wir Zusicherungen für Karten schreiben können.

Karten bestätigen

Wenn wir überprüfen möchten, ob eine Karte den angegebenen Schlüssel enthält, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den hasKey() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasKey;

@DisplayName("Writing assertions for maps")
class MapAssertionTest {
    
    private static final String KEY = "key";
    private static final String VALUE = "value";

    private Map<String, String> map;

    @BeforeEach
    void createAndInitializeMap() {
        map = new HashMap<>();
        map.put(KEY, VALUE);
    }

    @Nested
    @DisplayName("When we check if the map contains the given key")
    class WhenWeCheckIfMapContainsGivenKey {

        @Test
        @DisplayName("Should contain the correct key")
        void shouldContainCorrectKey() {
            assertThat(map, hasKey(KEY));
        }
    }
}

Wenn wir verifizieren wollen, dass eine Map den angegebenen Schlüssel nicht enthält, müssen wir die durch hasKey() angegebene Erwartung umkehren Methode mit not() Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.not;

@DisplayName("Writing assertions for maps")
class MapAssertionTest {

    private static final String INCORRECT_KEY = "incorrectKey";
    private static final String KEY = "key";
    private static final String VALUE = "value";

    private Map<String, String> map;

    @BeforeEach
    void createAndInitializeMap() {
        map = new HashMap<>();
        map.put(KEY, VALUE);
    }

    @Nested
    @DisplayName("When we check if the map contains the given key")
    class WhenWeCheckIfMapContainsGivenKey {

        @Test
        @DisplayName("Should not contain the incorrect key")
        void shouldNotContainIncorrectKey() {
            assertThat(map, not(hasKey(INCORRECT_KEY)));
        }
    }
}

Wenn wir sicherstellen wollen, dass eine Karte den richtigen Wert enthält, müssen wir unseren Hamcrest-Matcher erstellen, indem wir den hasEntry() aufrufen Methode des Matchers Klasse. Mit anderen Worten, wir müssen diese Behauptung verwenden:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasEntry;

@DisplayName("Writing assertions for maps")
class MapAssertionTest {
    
    private static final String KEY = "key";
    private static final String VALUE = "value";

    private Map<String, String> map;

    @BeforeEach
    void createAndInitializeMap() {
        map = new HashMap<>();
        map.put(KEY, VALUE);
    }

    @Nested
    @DisplayName("When we check if the map contains the correct value")
    class WhenWeCheckIfMapContainsCorrectValue {

        @Test
        @DisplayName("Should contain the correct value")
        void shouldContainCorrectValue() {
            assertThat(map, hasEntry(KEY, VALUE));
        }
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir mehrere Hamcrest-Matcher kombinieren können.

Hamcrest-Matcher kombinieren

Wir können jetzt mit Hamcrest grundlegende Assertionen schreiben. Manchmal müssen wir jedoch mehrere Hamcrest-Matcher kombinieren. Tatsächlich haben wir dies bereits getan, als wir die Erwartung eines Hamcrest-Matchers umkehrten, indem wir not() aufriefen Methode des Matchers Klasse.

Als Nächstes sehen wir uns zwei Beispiele an, die zeigen, wie wir Hamcrest-Matcher kombinieren können, wenn wir Behauptungen für Person schreiben Objekt. Der Quellcode von Person Klasse sieht wie folgt aus:

public class Person {
 
    private String firstName;
    private String lastName;
 
    public Person() {}
 
    public String getFirstName() {
        return firstName;
    }
 
    public String getLastName() {
        return lastName;
    }
 
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
 
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Wie wir sehen können, müssen wir sicherstellen, dass der behauptete Person, wenn wir überprüfen wollen, ob eine Person den richtigen Namen hat Objekt hat den richtigen Vor- und Nachnamen. Wenn wir diese Assertion schreiben, müssen wir den Hamcrest-Matcher erstellen, der an assertThat() übergeben wird Methode mithilfe dieser Hamcrest-Matcher:

  • Die allOf() Methode des Matchers Die Klasse gibt einen Hamcrest-Matcher zurück, der erwartet, dass das behauptete Objekt mit all übereinstimmt angegebene Hamcrest-Matcher.
  • Der hasProperty() Methode des Matchers Die Klasse gibt einen Matcher zurück, der es uns ermöglicht, Zusicherungen für die Eigenschaften des zugesicherten Objekts zu schreiben.
  • Der equalTo() Methode des Matchers Die Klasse gibt einen Matcher zurück, mit dem wir überprüfen können, ob der tatsächliche Wert der Eigenschaft dem erwarteten Wert entspricht.

Nachdem wir unsere Behauptung geschrieben haben, sieht sie wie folgt aus:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;

@DisplayName("Combine multiple assertions")
class CombineAssertionsTest {

    private static final String FIRST_NAME = "Jane";
    private static final String LAST_NAME = "Doe";

    private Person person;

    @BeforeEach
    void createPerson() {
        person = new Person();
        person.setFirstName(FIRST_NAME);
        person.setLastName(LAST_NAME);
    }

    @Test
    @DisplayName("Should have the correct name")
    void shouldHaveCorrectName() {
        assertThat(person, allOf(
                hasProperty("firstName", equalTo(FIRST_NAME)),
                hasProperty("lastName", equalTo(LAST_NAME))
        ));
    }
}

Wenn wir andererseits überprüfen möchten, ob eine Person den richtigen Vor- oder Nachnamen hat, müssen wir den Hamcrest-Matcher erstellen, der an assertThat() übergeben wird Methode mithilfe dieser Hamcrest-Matcher:

  • Der anyOf() Methode des Matchers Die Klasse gibt einen Hamcrest-Matcher zurück, der erwartet, dass das bestätigte Objekt mit beliebig übereinstimmt angegebenen Hamcrest-Matcher.
  • Der hasProperty() Methode des Matchers Die Klasse gibt einen Matcher zurück, der es uns ermöglicht, Zusicherungen für die Eigenschaften des zugesicherten Objekts zu schreiben.
  • Der equalTo() Methode des Matchers Die Klasse gibt einen Matcher zurück, mit dem wir überprüfen können, ob der tatsächliche Wert der Eigenschaft dem erwarteten Wert entspricht.

Nachdem wir unsere Behauptung geschrieben haben, sieht sie wie folgt aus:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;

@DisplayName("Combine multiple assertions")
class CombineAssertionsTest {

    private static final String FIRST_NAME = "Jane";
    private static final String LAST_NAME = "Doe";

    private Person person;

    @BeforeEach
    void createPerson() {
        person = new Person();
        person.setFirstName(FIRST_NAME);
        person.setLastName(LAST_NAME);
    }

    @Test
    @DisplayName("Should have correct first name or last name")
    void shouldHaveCorrectFirstNameOrLastName() {
        assertThat(person, anyOf(
                hasProperty("firstName", equalTo(FIRST_NAME)),
                hasProperty("lastName", equalTo(LAST_NAME))
        ));
    }
}

Als Nächstes werden wir herausfinden, wie wir eine benutzerdefinierte Fehlermeldung bereitstellen können, die angezeigt wird, wenn unsere Assertion fehlschlägt.

Eine benutzerdefinierte Fehlermeldung bereitstellen

Wie wir uns erinnern, müssen wir, wenn wir eine benutzerdefinierte Fehlermeldung angeben möchten, die angezeigt wird, wenn unsere Assertion fehlschlägt, diese Nachricht als ersten Methodenparameter von assertThat() übergeben Methode. Wir können diese Fehlermeldung erstellen, indem wir eine dieser beiden Optionen verwenden:

  • Wenn die Fehlermeldung keine Parameter hat, sollten wir einen String verwenden wörtlich.
  • Wenn die Fehlermeldung Parameter hat, sollten wir den static format() verwenden Methode des String Klasse.

Wenn wir beispielsweise eine Fehlermeldung erstellen möchten, die angezeigt wird, wenn die behauptete Liste das angegebene Element nicht enthält, müssen wir eine Behauptung erstellen, die wie folgt aussieht:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;

@DisplayName("Writing assertions for lists")
class ListAssertionTest {

    @Nested
    @DisplayName("When we write assertions for elements")
    class WhenWeWriteAssertionsForElements {

        private Object first;
        private Object second;

        private List<Object> list;

        @BeforeEach
        void createAndInitializeList() {
            first = new Object();
            second = new Object();

            list = Arrays.asList(first, second);
        }

        @Test
        @DisplayName("Should contain a correct element")
        void shouldContainCorrectElementWithCustomErrorMessage() {
            assertThat(String.format(
                            "The list doesn't contain the expected object: %s", 
                            first
                    ),
                    list,
                    hasItem(first)
            );
        }
    }
}

Wir können jetzt grundlegende Zusicherungen mit Hamcrest schreiben, mehrere Hamcrest-Matcher kombinieren und eine benutzerdefinierte Fehlermeldung bereitstellen, die angezeigt wird, wenn eine Zusicherung fehlschlägt.

Fassen wir zusammen, was wir aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogbeitrag hat uns vier Dinge gelehrt:

  • Bevor wir Assertions mit Hamcrest schreiben können, müssen wir sicherstellen, dass der hamcrest-library Abhängigkeit wird aus dem Klassenpfad gefunden.
  • Wenn wir Behauptungen mit Hamcrest schreiben wollen, müssen wir den assertThat() verwenden Methode des org.hamcrest.MatcherAssert Klasse.
  • Wenn wir eine benutzerdefinierte Fehlermeldung bereitstellen möchten, die angezeigt wird, wenn eine Assertion fehlschlägt, müssen wir diese Fehlermeldung als ersten Methodenparameter von assertThat() übergeben Methode.
  • Einige Methoden des Matchers -Klasse kann einen Hamcrest-Matcher (oder Matcher) als Methodenparameter annehmen. Mit diesen Methoden können wir mehrere Hamcrest-Matcher kombinieren.

Java-Tag