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

JUnit 5 Tutorial:At skrive påstande med AssertJ

Dette blogindlæg beskriver, hvordan vi kan skrive påstande med AssertJ. 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 AssertJ.
  • Forstå, hvordan vi kan tilpasse den fejlmeddelelse, der vises, når en påstand mislykkes.
  • Kan skrive bløde påstande med AssertJ.

Lad os begynde.

Få de nødvendige afhængigheder

Før vi kan skrive påstande med AssertJ, skal vi sikre, at assertj-core afhængighed (version 3.21.0) findes fra klassestien.

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

<dependency>
	<groupId>org.assertj</groupId>
	<artifactId>assertj-core</artifactId>
	<version>3.21.0</version>
	<scope>test</scope>
</dependency>

Hvis vi bruger Gradle, skal vi tilføje assertj-core 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.assertj:assertj-core:3.21.0'
    )
}

Efter at vi har tilføjet denne afhængighed til klassestien, kan vi skrive påstande med AssertJ. Lad os finde ud af, hvordan vi kan gøre det.

Skriv påstande med AssertJ

Når vi vil skrive påstande med AssertJ, skal vi bruge static assertThat() metoden for org.assertj.core.api.Assertions klasse. Når vi påberåber os denne metode, skal vi vide disse to ting:

  • assertThat() metoden tager den faktiske værdi eller objektet som en metodeparameter.
  • Assertions() klasse bruger metodeoverbelastning og typen af ​​objektet, der returneres af assertThat() metode afhænger af typen af ​​argumentet, der overføres til den pågældende metode.

Efter at vi har påkaldt assertThat() metode, kan vi skrive vores påstande ved at bruge det returnerede assertion objekt. Da AssertJ også leverer en flydende API, returnerer hver påstandsmetode en reference til det brugte påstandsobjekt. Det betyder, at vi kan sammenkæde påstande ved blot at påberåbe os en anden påstandsmetode.

Dernæst vil vi tage et kig på nogle eksempler, som viser, hvordan vi kan skrive påstande med AssertJ.

Bekræftelse af booleske værdier

Hvis vi ønsker at verificere, at en boolean værdien er true , skal vi skrive vores påstand ved at kalde isTrue() metode for AbstractBooleanAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.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).isTrue();
        }
    }
}

Hvis vi ønsker at bekræfte, at en boolean værdien er false , skal vi skrive vores påstand ved at påkalde isFalse() metoden for AbstractBooleanAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.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).isFalse();
        }
    }
}

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 skrive vores påstand ved at kalde isNull() metoden for AbstractAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

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

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

        private final Object NULL = null;

        @Test
        @DisplayName("Should be null")
        void shouldBeNull() {
            assertThat(NULL).isNull();
        }
    }
}

Hvis vi vil verificere, at et objekt ikke er null , skal vi skrive vores påstand ved at kalde isNotNull() metode for AbstractAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

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

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 ønsker at verificere, at den forventede værdi (eller objekt) er lig med den faktiske værdi (eller objekt), skal vi skrive vores påstand ved at påkalde enten isEqualTo() metode for AbstractAssert klasse eller isEqualByComparingTo() metoden for AbstractComparableAssert klasse. Forskellen på disse metoder er forklaret i det følgende:

  • isEqualTo() metode kalder equals() metode.
  • isEqualByComparingTo() metoden kalder compareTo() metoden til Comparable grænseflade.

For eksempel, hvis vi vil sikre, at to heltal er lige store, skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

@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).isEqualByComparingTo(EXPECTED);
            }
        }
    }
}

Hvis vi vil verificere, at den forventede værdi (eller objekt) ikke er lig med den faktiske værdi (eller objekt), skal vi skrive vores påstand ved at påkalde enten isNotEqualTo() metoden for AbstractAssert klasse eller isNotEqualByComparingTo() metoden for AbstractComparableAssert klasse. Disse metoder implementeres på samme måde som isEqualTo() og isEqualByComparingTo() metoder.

For eksempel, hvis vi vil sikre, at to heltal ikke er ens, skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

@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).isNotEqualByComparingTo(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 skrive vores påstand ved at kalde isSameAs() metoden for AbstractAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

@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).isSameAs(EXPECTED);
        }
    }
}

Hvis vi vil sikre, at to objekter ikke refererer til det samme objekt, skal vi skrive vores påstand ved at påkalde isNotSameAs() metoden for AbstractAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

@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).isNotSameAs(EXPECTED);
        }
    }
}

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

påstand om, at to arrays er ens

Hvis vi vil verificere, at to arrays er ens, skal vi skrive vores påstand ved at kalde isEqualTo() metoden for AbstractArrayAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

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

    @Nested
    @DisplayName("When two arrays are equal")
    class WhenArraysAreEqual {

        @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).isEqualTo(EXPECTED);
            }
        }
    }
}

Hvis vi vil verificere, at to arrays ikke er ens, skal vi skrive vores påstand ved at kalde isNotEqualTo() metoden for AbstractArrayAssert klasse. Med andre ord skal vi bruge en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

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

    @Nested
    @DisplayName("When two arrays are not equal")
    class WhenArraysAreNotEqual {

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

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

            @Test
            @DisplayName("Should not contain the same integers")
            void shouldNotContainSameIntegers() {
                assertThat(ACTUAL).isNotEqualTo(EXPECTED);
            }
        }
    }
}

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

Skrivning af påstande for iterables

Hvis vi ønsker at skrive en påstand, som bekræfter, at størrelsen af ​​en Iterable er korrekt, kan vi bruge en af ​​disse tre muligheder:

  • Hvis vi vil bekræfte, at en iterabel er tom, kan vi skrive vores påstand ved at påkalde isEmpty() metoden for AbstractIterableAssert klasse.
  • Hvis vi vil sikre, at en iterabel ikke er tom, kan vi skrive vores påstand ved at påkalde isNotEmpty() metoden for AbstractIterableAssert klasse.
  • Hvis vi ønsker at verificere, at størrelsen af ​​den iterable er korrekt, kan vi skrive vores påstand ved at påkalde hasSize() metoden for AbstractIterableAssert klasse.

For eksempel, hvis vi vil sikre, at en liste indeholder to elementer, skal vi bruge 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.assertj.core.api.Assertions.assertThat;

@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 sikre, at en iterabel kun indeholder de forventede elementer i den givne rækkefølge, skal vi skrive vores påstand ved at bruge containsExactly() metoden for AbstractIterableAssert 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.assertj.core.api.Assertions.assertThat;

@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).containsExactly(first, second);
        }
    }
}

Hvis vi vil verificere, at en iterabel kun indeholder de forventede elementer i en hvilken som helst rækkefølge, skal vi skrive vores påstand ved at bruge containsExactlyInAnyOrder() metoden for AbstractIterableAssert 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.assertj.core.api.Assertions.assertThat;

@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).containsExactlyInAnyOrder(second, first);
        }
    }
}

Hvis vi vil sikre, at en iterabel indeholder det angivne element, skal vi skrive vores påstand ved at bruge containsOnlyOnce() metode for AbstractIterableAssert 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.assertj.core.api.Assertions.assertThat;

@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 element once")
        void shouldContainCorrectElementOnce() {
            assertThat(list).containsOnlyOnce(first);
        }
    }
}

Hvis vi vil sikre, at en iterable ikke indeholder det angivne element, skal vi skrive vores påstand ved at bruge doesNotContain() metoden for AbstractIterableAssert klasse. For eksempel, hvis vi vil verificere, at vores liste ikke indeholder det angivne objekt, 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.assertj.core.api.Assertions.assertThat;

@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).doesNotContain(new Object());
        }
    }
}

Hvis vi vil verificere, at to iterables er dybt lige store, skal vi skrive vores påstand ved at bruge isEqualTo() metoden for AbstractAssert 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.assertj.core.api.Assertions.assertThat;

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

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

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

        @Test
        @DisplayName("Should contain the same elements")
        void shouldContainSameElements() {
            assertThat(FIRST).isEqualTo(SECOND);
        }
    }
}

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

Skriv påstande til kort

Hvis vi vil sikre, at et kort indeholder den angivne nøgle, skal vi skrive vores påstand ved at påkalde containsKey() metoden for AbstractMapAssert klasse. Med andre ord skal vi bruge 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.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;


@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 verify that the map contains the given key")
    class WhenWeVerifyThatMapContainsGivenKey {

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

Hvis vi vil sikre, at et kort ikke indeholder den angivne nøgle, skal vi skrive vores påstand ved at påkalde doesNotContainKey() metoden for AbstractMapAssert klasse. Med andre ord skal vi bruge 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.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;


@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 verify that the map doesn't contain the given key")
    class WhenWeVerifyThatMapDoesNotContainGivenKey {

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

Hvis vi vil sikre, at et kort indeholder den angivne post, skal vi skrive vores påstand ved at påkalde containsEntry() metoden for AbstractMapAssert klasse. Med andre ord skal vi bruge 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.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;


@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 verify that the map contains the given entry")
    class WhenWeVerifyThatMapContainsGivenEntry {

        @Test
        @DisplayName("Should contain the given entry")
        void shouldContainGivenEntry() {
            assertThat(map).containsEntry(KEY, VALUE);
        }
    }
}

Hvis vi vil sikre, at et kort ikke indeholder den angivne post, skal vi skrive vores påstand ved at påkalde doesNotContainEntry() metoden for AbstractMapAssert klasse. Med andre ord skal vi bruge 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.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;


@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 verify that the map doesn't contain the given entry")
    class WhenWeVerifyThatMapDoesNotContainGivenEntry {

        @Test
        @DisplayName("Should not contain the given entry")
        void shouldContainGivenEntry() {
            assertThat(map).doesNotContainEntry(INCORRECT_KEY, VALUE);
        }
    }
}

Lad os gå videre og finde ud af, hvordan vi kan skrive påstande for de undtagelser, som det system, der testes, giver.

Skrive påstande for undtagelser

Hvis vi ønsker at skrive påstande for den undtagelse, der er smidt af systemet under test, kan vi bruge en af ​​disse to muligheder:

Først , kan vi bruge static assertThatThrownBy() metode for org.assertj.core.api.Assertions klasse. Når vi bruger denne metode, skal vi vide disse to ting:

  • Det kræver en ThrowingCallable objekt som metodeparameter. Dette objekt kalder systemet under test.
  • Det returnerer en AbstractThrowableAssert objekt. Vi er nødt til at bruge dette objekt, når vi skriver påstande for den undtagelse, der er smidt af systemet under test.

Lad os tage et kig på to eksempler, der viser, hvordan vi kan skrive påstande ved at bruge denne tilgang:

Hvis vi vil verificere, at systemet under test afgiver den forventede undtagelse, skal vi skrive vores påstand ved at bruge isExactlyInstanceOf() metoden for AbstractThrowableAssert klasse. For eksempel, hvis vi ønsker at verificere, at systemet under test kaster en NullPointerException , skal vi skrive en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThatThrownBy;

@DisplayName("Writing assertions for exceptions")
class ExceptionAssertionTest {

    @Nested
    @DisplayName("When we write assertions directly to the thrown exception")
    class WhenWeWriteAssertionsForThrownException {

        @Nested
        @DisplayName("When the system under test throws the correct exception")
        class WhenSystemUnderTestThrowsException {

            @Test
            @DisplayName("Should throw the correct exception")
            void shouldThrowCorrectException() {
                assertThatThrownBy(() -> { throw new NullPointerException(); })
                        .isExactlyInstanceOf(NullPointerException.class);
            }
        }
    }
}

Hvis vi ønsker at verificere, at systemet under test afgiver en undtagelse, der har den forventede besked, skal vi skrive vores påstand ved at bruge hasMessage() metoden for AbstractThrowableAssert klasse. For eksempel, hvis vi ønsker at verificere, at systemet under test afgiver en undtagelse, der har meddelelsen:'Hello World!', skal vi skrive en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThatThrownBy;

@DisplayName("Writing assertions for exceptions")
class ExceptionAssertionTest {

    @Nested
    @DisplayName("When we write assertions directly to the thrown exception")
    class WhenWeWriteAssertionsForThrownException {

        @Nested
        @DisplayName("When SUT throws an exception that has the correct message")
        class WhenSystemUnderTestThrowsExceptionWithCorrectMessage {

            @Test
            @DisplayName("Should throw an exception that has the correct message")
            void shouldThrowAnExceptionWithCorrectMessage() {
                assertThatThrownBy(() -> { 
                    throw new NullPointerException("Hello World!"); 
                })
                        .hasMessage("Hello World!");
            }
        }
    }
}

Anden , kan vi fange den kastede undtagelse ved at bruge static catchThrowable() metoden for org.assertj.core.api.Assertions klasse. Denne metode kan tage to metodeparametre, som er beskrevet i det følgende:

  • A ThrowingCallable objekt, der kalder systemet under test.
  • A Class objekt, der angiver typen af ​​den forventede undtagelse. Dette er en valgfri parameter, og hvis vi sender den til catchThrowable() metode, angiver den typen af ​​det returnerede undtagelsesobjekt. Hvis vi udelader denne metodeparameter, vil catchThrowable() metode returnerer en Throwable objekt.

Lad os tage et kig på to eksempler, der viser, hvordan vi kan skrive påstande ved at bruge denne tilgang:

Hvis vi vil verificere, at systemet under test afgiver den forventede undtagelse, skal vi skrive vores påstand ved at bruge isExactlyInstanceOf() metoden for AbstractThrowableAssert klasse. For eksempel, hvis vi ønsker at verificere, at systemet under test kaster en NullPointerException , skal vi skrive en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;

@DisplayName("Writing assertions for exceptions")
class ExceptionAssertionTest {

    @Nested
    @DisplayName("When we catch the thrown exception object")
    class WhenWeCatchThrownExceptionObject {

        @Nested
        @DisplayName("When the system under test throws the correct exception")
        class WhenSystemUnderTestThrowsException {

            @Test
            @DisplayName("Should throw the correct exception")
            void shouldThrowCorrectException() {
                final Throwable thrown = catchThrowable(() -> { 
                    throw new NullPointerException(); 
                });
                assertThat(thrown).isExactlyInstanceOf(NullPointerException.class);
            }
        }
    }
}

Hvis vi vil verificere, at systemet under test afgiver en undtagelse, der har den forventede besked, skal vi skrive vores påstand ved at bruge hasMessage() metoden for AbstractThrowableAssert klasse. For eksempel, hvis vi ønsker at verificere, at systemet under test afgiver en undtagelse, der har meddelelsen:'Hello World!', skal vi skrive en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;

@DisplayName("Writing assertions for exceptions")
class ExceptionAssertionTest {

    @Nested
    @DisplayName("When we catch the thrown exception object")
    class WhenWeCatchThrownExceptionObject {

        @Nested
        @DisplayName("When the system under test throws an exception that has the correct message")
        class WhenSystemUnderTestThrowsExceptionWithCorrectMessage {

            @Test
            @DisplayName("Should throw an exception that has the correct message")
            void shouldThrowAnExceptionWithCorrectMessage() {
                final Throwable thrown = catchThrowable(() -> {
                    throw new NullPointerException("Hello World!"); }
                    );
                assertThat(thrown.getMessage()).isEqualTo("Hello World!");
            }
        }
    }
}

Dernæst vil vi finde ud af, hvordan vi kan skrive påstande for Optional genstande.

Skrivning af påstande til valgfrie objekter

Hvis vi ønsker at sikre, at en Optional objektet er tomt, skal vi skrive vores påstand ved at kalde isEmpty() metoden for AbstractOptionalAssert klasse. Med andre ord skal vi skrive en påstand, der ser ud som følger:

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

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("Writing assertions for Optional objects")
class OptionalAssertionTest {

    @Nested
    @DisplayName("When the optional is empty")
    class WhenOptionalIsEmpty {

        @Test
        @DisplayName("Should be empty")
        void shouldBeEmpty() {
            assertThat(Optional.empty()).isEmpty();
        }
    }
}

Hvis vi ønsker at sikre, at en Optional objektet ikke er tomt, skal vi skrive vores påstand ved at påkalde isNotEmpty() metode for AbstractOptionalAssert klasse. Med andre ord skal vi skrive en påstand, der ser ud som følger:

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

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("Writing assertions for Optional objects")
class OptionalAssertionTest {

    @Nested
    @DisplayName("When the optional is not empty")
    class WhenOptionalIsNotEmpty {

        @Test
        @DisplayName("Should not be empty")
        void shouldNotBeEmpty() {
            assertThat(Optional.of(new Object())).isNotEmpty();
        }
    }
}

Hvis vi ønsker at sikre, at en Optional objektet indeholder det forventede objekt, skal vi skrive vores påstand ved at kalde contains() metoden for AbstractOptionalAssert klasse. Med andre ord skal vi skrive en påstand, der ser ud som følger:

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

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("Writing assertions for Optional objects")
class OptionalAssertionTest {

    @Nested
    @DisplayName("When the optional is not empty")
    class WhenOptionalIsNotEmpty {

        private final Object OBJECT = new Object();

        @Test
        @DisplayName("Should contain the correct object")
        void shouldContainCorrectObject() {
            assertThat(Optional.of(OBJECT)).contains(OBJECT);
        }
    }
}

Lad os gå videre og finde ud af, hvordan vi kan angive en brugerdefineret fejlmeddelelse, der vises, når en påstand mislykkes.

Udgivelse af en brugerdefineret fejlmeddelelse

Selvom AssertJ har meget gode fejlmeddelelser, vil vi nogle gange gerne understrege den forretningsregel, der håndhæves af vores påstand. Når vi ønsker at gøre dette, kan vi give en brugerdefineret fejlmeddelelse ved at bruge en af ​​disse to muligheder:

  • Hvis vi ønsker at tilsidesætte beskrivelsesdelen af ​​fejlmeddelelsen, skal vi enten kalde as() eller describedAs() metoden for Descriptable grænseflade.
  • Hvis vi vil tilsidesætte hele fejlmeddelelsen, skal vi aktivere overridingErrorMessage() metoden for AbstractAssert klasse.

Alle disse metoder kan tage to metodeparametre, som er forklaret i det følgende:

  • A String objekt, som indeholder fejlmeddelelsen. Hvis vi ønsker at give en dynamisk fejlmeddelelse, kan vi bruge formatet understøttet af String.format() metode.
  • En valgfri Object array, som indeholder parametrene for vores fejlmeddelelse. Denne metodeparameter sendes til String.format() metode, der opretter den faktiske fejlmeddelelse. Det er derfor, vi ikke behøver at give denne metodeparameter, hvis vi bruger en statisk fejlmeddelelse.

Lad os tage et kig på to eksempler, der viser forskellen på disse muligheder.

Først , hvis vi kun ønsker at tilsidesætte beskrivelsesdelen af ​​den viste fejlmeddelelse, skal vi skrive en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("Provide a custom error message")
class CustomErrorMessageTest {

    @Nested
    @DisplayName("When we provide only the description")
    class WhenWeProvideOnlyDescription {

        @Test
        @DisplayName("Should override only the description")
        void shouldBeFalseWithCustomErrorMessage() {
            assertThat(false)
                    .describedAs("The boolean is not false")
                    .isFalse();
        }
    }
}

Hvis vores påstand mislykkes, ser vi en fejlmeddelelse, der ser ud som følger:

org.opentest4j.AssertionFailedError: [The boolean is not false] 
Expecting: <true> to be equal to: <false> but was not.
Expected :false
Actual   :true

Anden , hvis vi vil tilsidesætte hele fejlmeddelelsen, skal vi skrive en påstand, der ser ud som følger:

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

import static org.assertj.core.api.Assertions.assertThat;

@DisplayName("Provide a custom error message")
class CustomErrorMessageTest {

    @Nested
    @DisplayName("When we provide the entire error message")
    class WhenWeProvideEntireErrorMessage {

        @Test
        @DisplayName("Should override entire error message")
        void shouldBeFalseWithCustomErrorMessage() {
            assertThat(false)
                    .overridingErrorMessage("The boolean is not false")
                    .isFalse();
        }
    }
}

Hvis vores påstand mislykkes, ser vi en fejlmeddelelse, der ser ud som følger:

java.lang.AssertionError: The boolean is not false

Lad os gå videre og finde ud af, hvordan vi kan skrive bløde påstande med AssertJ.

Skriv bløde påstande

Hvis vi skal skrive en påstand for en tilstand, der kræver flere påstande, er det en god idé at køre alle påstande og rapportere alle påstandsfejl, efter at alle påstande er blevet kørt. Vi kan gøre dette med AssertJ ved at bruge bløde påstande.

Lad os antage, at vi skal skrive en påstand, der bekræfter, at en Person objektet har det korrekte navn. 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 vil verificere, at en person har det korrekte navn, skal vi verificere, at den påståede Person objektet har det korrekte for- og efternavn. Vi kan skrive vores påstand ved at følge disse trin:

  1. Opret en ny SoftAssertions objekt.
  2. Sørg for, at Person objektet har det korrekte fornavn.
  3. Bekræft, at Person objektet har det korrekte efternavn.
  4. Kør alle påstande ved at kalde assertAll() metode til SoftAssertions klasse. Denne metode kører alle specificerede påstande og rapporterer påstandsfejl, efter at disse påstande er blevet kørt.

Efter at vi har skrevet de påkrævede bløde påstande, ser kildekoden for vores testklasse ud som følger:

import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("Collect all error messages before reporting them")
class SoftAssertionsTest {

    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() {
        SoftAssertions softAssertions = new SoftAssertions();

        softAssertions.assertThat(person.getFirstName())
                .overridingErrorMessage(
                        "Expected the first name to be: %s but it was: %s",
                        FIRST_NAME,
                        person.getFirstName()
                )
                .isEqualTo(FIRST_NAME);
        softAssertions.assertThat(person.getLastName())
                .overridingErrorMessage(
                        "Expected the last name to be: %s but it was: %s",
                        LAST_NAME,
                        person.getLastName()
                )
                .isEqualTo(LAST_NAME);

        softAssertions.assertAll();
    }
}

Vi kan nu skrive grundlæggende påstande med AssertJ, give en brugerdefineret fejlmeddelelse, der vises, når en påstand mislykkes, og skrive bløde påstande med AssertJ.

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

Oversigt

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

  • Før vi kan skrive påstande med AssertJ, skal vi sikre, at assertj-core afhængighed findes fra klassestien.
  • Vi kan skrive påstande med AssertJ ved at bruge static metoder for org.assertj.core.api.Assertions klasse.
  • Hvis vi vil tilsidesætte beskrivelsesdelen af ​​fejlmeddelelsen, der vises, når en påstand mislykkes, skal vi bruge enten as() eller describedAs() metoder for Descriptable grænseflade.
  • Hvis vi vil tilsidesætte hele den fejlmeddelelse, der vises, når en påstand mislykkes, skal vi aktivere overridingErrorMessage() metode for AbstractAssert klasse.
  • Vi kan skrive bløde påstande med AssertJ ved at bruge org.assertj.core.api.SoftAssertions klasse.

Java tag