Java >> Java tutorial >  >> Tag >> assert

JUnit 5 Tutorial:At skrive påstande med Hamcrest

Dette blogindlæg beskriver, hvordan vi kan skrive påstande med Hamcrest. Efter at vi har afsluttet dette blogindlæg, gør vi:

  • Kan få de nødvendige afhængigheder med Maven og Gradle.
  • Vid, hvordan vi kan skrive grundlæggende påstande med Hamcrest.
  • Forstå, hvordan vi kan kombinere flere Hamcrest-matchere.
  • Kan tilpasse den fejlmeddelelse, der vises, når en påstand mislykkes.

Lad os begynde.

Få de nødvendige afhængigheder

Før vi kan skrive påstande med Hamcrest, skal vi sikre, at hamcrest-library afhængighed (version 2.2) findes fra klassestien.

Hvis vi bruger Maven, skal vi tilføje hamcrest-library afhængighed af test omfang. Vi kan gøre dette ved at tilføje følgende uddrag til depencies sektion af vores pom.xml fil:

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

Hvis vi bruger Gradle, skal vi tilføje hamcrest-library afhængighed af testImplementation afhængighedskonfiguration. Vi kan gøre dette ved at tilføje følgende uddrag til vores build.gradle fil:

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

Efter at vi har sikret, at hamcrest-library afhængighed findes fra klassestien, kan vi skrive påstande med Hamcrest. Lad os finde ud af, hvordan vi kan gøre det.

Skriv påstande med Hamcrest

Hvis du har brugt Hamcrest med JUnit 4, vil du sikkert huske, at du skulle bruge assertThat() metoden for org.junit.Assert klasse. JUnit 5 API'et har dog ikke en metode, der tager en Hamcrest-matcher som en metodeparameter. JUnit 5-brugervejledningen forklarer denne designbeslutning som følger:

Men JUnit Jupiters org.junit.jupiter.api.Assertions klasse giver ikke en assertThat() metode som den, der findes i JUnit 4's org.junit.Assert klasse, som accepterer en Hamcrest Matcher . I stedet opfordres udviklere til at bruge den indbyggede understøttelse af matchere, som leveres af tredjeparts påstandsbiblioteker.

Med andre ord, hvis vi vil bruge Hamcrest-matchere, skal vi bruge assertThat() metode til org.hamcrest.MatcherAssert klasse. Denne metode tager enten to eller tre metodeparametre, som er beskrevet i det følgende:

  1. En valgfri fejlmeddelelse, der vises, når vores påstand mislykkes.
  2. Den faktiske værdi eller objekt.
  3. En Matcher objekt, der angiver den forventede værdi. Vi kan oprette ny Matcher objekter ved at bruge static fabriksmetoder leveret af org.hamcrest.Matchers klasse.

Dernæst vil vi tage et kig på nogle eksempler, som viser, hvordan vi kan skrive påstande med Hamcrest. Lad os starte med at finde ud af, hvordan vi kan skrive påstande for boolean værdier.

Bekræftelse af booleske værdier

Hvis vi ønsker at bekræfte, at en boolean værdien er true , skal vi oprette vores Hamcrest-matcher ved at kalde is() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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));
        }
    }
}

Hvis vi ønsker at verificere, at en boolean værdien er false , skal vi oprette vores Hamcrest-matcher ved at kalde is() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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));
        }
    }
}

Lad os gå videre og finde ud af, hvordan vi kan verificere, at et objekt er null eller er det ikke null .

Bekræftelse af, at et objekt er nul eller ikke er nul

Hvis vi vil verificere at et objekt er null , skal vi oprette vores Hamcrest-matcher ved at kalde nullValue() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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());
        }
    }
}

Hvis vi vil verificere, at et objekt ikke er null , skal vi oprette vores Hamcrest-matcher ved at kalde notNullValue() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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());
        }
    }
}

Dernæst vil vi finde ud af, hvordan vi kan verificere, at to objekter (eller værdier) er ens eller ikke er ens.

Bekræftelse af, at to objekter eller værdier er ens

Hvis vi vil verificere, at den forventede værdi (eller objekt) er lig med den faktiske værdi (eller objekt), skal vi oprette vores Hamcrest-matcher ved at kalde equalTo() metoden for Matchers klasse. For eksempel, hvis vi ønsker at sammenligne to Integer objekter, skal vi bruge denne påstand:

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));
            }
        }
    }
}

Hvis vi vil verificere, at den forventede værdi (eller objekt) ikke er lig med den faktiske værdi (eller objekt), skal vi oprette vores Hamcrest-matcher ved at kalde not() metoden for Matchers klasse. For eksempel, hvis vi ønsker at sammenligne to Integer objekter, skal vi bruge denne påstand:

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));
            }
        }
    }
}

Lad os gå videre og finde ud af, hvordan vi kan skrive påstande til objektreferencer.

Påhævelse af objektreferencer

Hvis vi vil sikre, at to objekter refererer til det samme objekt, skal vi oprette vores Hamcrest-matcher ved at kalde sameInstance() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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));
        }
    }
}

Hvis vi vil sikre, at to objekter ikke refererer til det samme objekt, skal vi vende forventningen angivet af sameInstance() metode ved at bruge not() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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)));
        }
    }
}

Dernæst vil vi finde ud af, hvordan vi kan verificere, at to arrays er ens.

påstand om, at to arrays er ens

Hvis vi vil verificere, at to arrays er ens, skal vi oprette vores Hamcrest-matcher ved at kalde equalTo() metoden for Matchers klasse. For eksempel, hvis vi vil bekræfte, at to int arrays er ens, skal vi bruge denne påstand:

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));
        }
    }
}

Lad os gå videre og finde ud af, hvordan vi kan skrive påstande til lister.

Gældende lister

Hvis vi vil skrive en påstand, der bekræfter, at størrelsen af ​​en liste er korrekt, skal vi oprette vores Hamcrest-matcher ved at kalde hasSize() metoden for Matchers klasse. For eksempel, hvis vi vil verificere, at størrelsen af ​​en liste er 2, skal vi bruge denne påstand:

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));
        }
    }
}

Hvis vi vil verificere, at listen kun indeholder de forventede elementer i den givne rækkefølge, skal vi oprette vores Hamcrest-matcher ved at kalde contains() metoden for Matchers klasse. For eksempel, hvis vi vil verificere, at vores liste indeholder de korrekte elementer i den givne rækkefølge, skal vi bruge denne påstand:

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));
        }
    }
}

Hvis vi ønsker at verificere, at listen kun indeholder de forventede elementer i en hvilken som helst rækkefølge, skal vi oprette vores Hamcrest-matcher ved at kalde containsInAnyOrder() metoden for Matchers klasse. For eksempel, hvis vi vil verificere, at vores liste indeholder de korrekte elementer i en hvilken som helst rækkefølge, skal vi bruge denne påstand:

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));
        }
    }
}

Hvis vi vil sikre, at en liste indeholder det givne element, skal vi oprette vores Hamcrest-matcher ved at påkalde hasItem() metoden for Matchers klasse. For eksempel, hvis vi ønsker at bekræfte, at vores liste indeholder Object der er gemt i feltet kaldet first , vi skal bruge denne påstand:

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));
        }
    }
}

Hvis vi vil sikre, at en liste ikke indeholder et element, skal vi vende forventningen angivet af hasItem() metode ved at bruge not() metoden for Matchers klasse. Med ordene skal vi bruge denne påstand:

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())));
        }
    }
}

Hvis vi vil verificere, at to lister er dybt ens, skal vi oprette vores Hamcrest-matcher ved at påkalde equalTo() metoden for Matchers klasse. For eksempel, hvis vi vil bekræfte, at to Integer lister er dybt lige, skal vi bruge denne påstand:

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));
        }
    }
}

Dernæst vil vi finde ud af, hvordan vi kan skrive påstande til kort.

Bekræftelse af kort

Hvis vi vil verificere, at et kort indeholder den givne nøgle, skal vi oprette vores Hamcrest-matcher ved at kalde hasKey() metoden for Matchers klasse. Med andre ord, vi skal bruge denne påstand:

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));
        }
    }
}

Hvis vi vil verificere, at et kort ikke indeholder den givne nøgle, skal vi vende forventningen angivet af hasKey() metode ved at bruge not() metoden for Matchers klasse. Med andre ord, vi skal bruge denne påstand:

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)));
        }
    }
}

Hvis vi vil sikre, at et kort indeholder den korrekte værdi, skal vi oprette vores Hamcrest-matcher ved at påkalde hasEntry() metoden for Matchers klasse. Med andre ord, vi skal bruge denne påstand:

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));
        }
    }
}

Lad os gå videre og finde ud af, hvordan vi kan kombinere flere Hamcrest-matchere.

Kombinering af Hamcrest Matchers

Vi kan nu skrive grundlæggende påstande med Hamcrest. Nogle gange er vi dog nødt til at kombinere flere Hamcrest-matchere. Faktisk gjorde vi allerede dette, da vi vendte forventningen om en Hamcrest-matcher ved at påkalde not() metode for Matchers klasse.

Dernæst vil vi tage et kig på to eksempler, som viser, hvordan vi kan kombinere Hamcrest-matchere, når vi skriver påstande til en Person objekt. Kildekoden til Person klasse ser ud som følger:

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;
    }
}

Som vi kan se, hvis vi ønsker at verificere, at en person har det korrekte navn, skal vi sikre, at den hævdede Person objektet har det korrekte for- og efternavn. Når vi skriver denne påstand, skal vi oprette Hamcrest-matcheren, der er videregivet til assertThat() metode ved at bruge disse Hamcrest Matchers:

  • allOf() metoden for Matchers klasse returnerer en Hamcrest-matcher, som forventer, at det påståede objekt matcher med alle specificerede Hamcrest matchers.
  • hasProperty() metoden for Matchers klasse returnerer en matcher, som giver os mulighed for at skrive påstande for egenskaberne for det hævdede objekt.
  • equalTo() metoden for Matchers klasse returnerer en matcher, som giver os mulighed for at verificere, at den faktiske ejendomsværdi er lig med den forventede værdi.

Efter at vi har skrevet vores påstand, ser den ud som følger:

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))
        ));
    }
}

På den anden side, hvis vi vil bekræfte, at en person har det korrekte fornavn eller efternavn, skal vi oprette Hamcrest-matcheren, der er videregivet til assertThat() metode ved at bruge disse Hamcrest Matchers:

  • anyOf() metoden for Matchers klasse returnerer en Hamcrest-matcher, som forventer, at det hævdede objekt matcher med enhver specificeret Hamcrest matcher.
  • hasProperty() metoden for Matchers klasse returnerer en matcher, som giver os mulighed for at skrive påstande for egenskaberne for det hævdede objekt.
  • equalTo() metoden for Matchers klasse returnerer en matcher, som giver os mulighed for at verificere, at den faktiske ejendomsværdi er lig med den forventede værdi.

Efter at vi har skrevet vores påstand, ser den ud som følger:

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))
        ));
    }
}

Dernæst vil vi finde ud af, hvordan vi kan levere en brugerdefineret fejlmeddelelse, der vises, når vores påstand mislykkes.

Udgivelse af en brugerdefineret fejlmeddelelse

Som vi husker, hvis vi ønsker at angive en brugerdefineret fejlmeddelelse, der vises, når vores påstand mislykkes, skal vi sende denne meddelelse som den første metodeparameter i assertThat() metode. Vi kan oprette denne fejlmeddelelse ved at bruge en af ​​disse to muligheder:

  • Hvis fejlmeddelelsen ikke har nogen parametre, skal vi bruge en String bogstaveligt.
  • Hvis fejlmeddelelsen har parametre, skal vi bruge static format() metoden for String klasse.

For eksempel, hvis vi ønsker at oprette en fejlmeddelelse, der vises, når den hævdede liste ikke indeholder det givne element, skal vi oprette en påstand, der ser ud som følger:

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)
            );
        }
    }
}

Vi kan nu skrive grundlæggende påstande med Hamcrest, kombinere flere Hamcrest-matchere og give en brugerdefineret fejlmeddelelse, der vises, når en påstand mislykkes.

Lad os opsummere, hvad vi lærte fra dette blogindlæg.

Oversigt

Dette blogindlæg har lært os fire ting:

  • Før vi kan skrive påstande med Hamcrest, skal vi sikre, at hamcrest-library afhængighed findes fra klassestien.
  • Hvis vi vil skrive påstande med Hamcrest, skal vi bruge assertThat() metoden for org.hamcrest.MatcherAssert klasse.
  • Hvis vi vil give en brugerdefineret fejlmeddelelse, der vises, når en påstand mislykkes, skal vi sende denne fejlmeddelelse som den første metodeparameter i assertThat() metode.
  • Nogle metoder til Matchers klasse kan tage en Hamcrest-matcher (eller matchers) som en metodeparameter. Vi kan kombinere flere Hamcrest matchere ved at bruge disse metoder.

Java tag