Tuesday, November 19, 2024
Google search engine
HomeLanguagesJavaJUnit 5 – Asserting Arrays and Lists with AssertJ

JUnit 5 – Asserting Arrays and Lists with AssertJ

JUnit is a unit testing framework for the Java programming language. JUnit has been important in the development of test-driven development. JUnit 5 is the next generation of JUnit. AssertJ is a Java library that provides a rich set of assertions and truly helpful error messages, improves test code readability, and is designed to be super easy to use within your favorite IDE. In this article let us see how to write test cases with AssertJ for Arrays and Lists with the JUnit 5 framework. Following are the advantages of the JUnit 5 framework:

  • @DisplayName: Used to tell about which test is getting executed and we will come to know at any point in time, the output result by seeing the text appearing in @DisplayName and we can maintain it hierarchically too.
  • @Nested to make the test go to any depth and in this way, categorization is easier.

With a sample project, we can check that.

Example Project

Project Structure:

Project Structure

 

As it is a maven project, let us check for the dependencies

<!-- For using assertj, this dependency is needed -->
<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <version>3.21.0</version>
  <scope>test</scope>
</dependency>
<!-- For using assertj, this dependency is needed -->

pom.xml

XML




         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             https://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>gfg.sample.junit5</groupId>
    <artifactId>sampleproject-assertions-with-assertj</artifactId>
    <version>0.1</version>
    <name>Writing Assertions With AssertJ</name>
    <description>
        This example demonstrates how we can write assertions with AssertJ.
    </description>
 
    <properties>
        <jdk.version>1.8</jdk.version>
        <junit.jupiter.version>5.8.2</junit.jupiter.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
     
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.jupiter.version}</version>
            <scope>test</scope>
        </dependency>
      <!-- For using assertj, this dependency is needed -->
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.21.0</version>
            <scope>test</scope>
        </dependency>
      <!-- For using assertj, this dependency is needed -->
    </dependencies>
    <build>
        <finalName>sampleproject-assertions-with-assertj</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>
</project>


In this sample project, we are going to cover the tests with Assertj for Arrays and Lists

ArrayAssertionSampleTest.java

Java




import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
 
import java.util.Arrays;
 
import static org.assertj.core.api.Assertions.assertThat;
 
// This class demonstrates how we can write
// assertions for arrays by using AssertJ.
// By using @Nested, we are deeply adding
// the testcases and in this way we can
// cover all testcases
@DisplayName("Writing assertions for arrays")
class ArrayAssertionSampleTest {
 
    @Nested
    @DisplayName("Checking whether when two arrays are having equal values")
    class WhenArrayValuesAreEqual {
 
        @Nested
        @DisplayName("When arrays contain integers")
        class WhenArraysContainIntegers {
 
            final int[] ACTUAL = new int[]{25, 50, 75,100};
            final int[] EXPECTED = new int[]{25, 50, 75,100};
 
            @Test
            @DisplayName("Test to check when they contain the same integers")
            void checkForSameIntegers() {
                assertThat(ACTUAL).isEqualTo(EXPECTED);
            }
 
            @Test
            @DisplayName("Test to check when they contain the same integers (with custom error message)")
            void checkForSameIntegersWithCustomErrorMessage() {
                assertThat(ACTUAL)
                        .overridingErrorMessage(
                                "Expected array: %s but got array: %s",
                                Arrays.toString(EXPECTED),
                                Arrays.toString(ACTUAL)
                        )
                        .isEqualTo(EXPECTED);
            }
        }
 
        @Nested
        @DisplayName("When arrays contain strings as values")
        class WhenArraysContainStringsAsValues {
 
            final String[] ACTUAL = new String[] {"Monica", "Geller"};
            final String[] EXPECTED = new String[] {"Monica", "Geller"};
 
            @Test
            @DisplayName("Test to check whether strings match")
            void testToCheckForSameStrings() {
                assertThat(ACTUAL).isEqualTo(EXPECTED);
            }
 
            @Test
            @DisplayName("Test to check whether strings match (with custom error message)")
            void testToCheckForSameStringsWithCustomErrorMessage() {
                assertThat(ACTUAL)
                        .overridingErrorMessage(
                                "Expected array: %s but got array: %s",
                                Arrays.toString(EXPECTED),
                                Arrays.toString(ACTUAL)
                        )
                        .isEqualTo(EXPECTED);
            }
        }
    }
 
    @Nested
    @DisplayName("When two array values are not equal")
    class WhenArrayValuesAreNotEqual {
 
        @Nested
        @DisplayName("When arrays contain integers")
        class WhenArraysContainIntegerValues {
 
            final int[] ACTUAL = new int[]{200, 6000, 70000,10};
            final int[] EXPECTED = new int[]{20, 600, 7000,1};
 
            @Test
            @DisplayName("When they do not contain the same integers")
            void whenTheyDoNotContainSameIntegers() {
                assertThat(ACTUAL).isNotEqualTo(EXPECTED);
            }
 
            @Test
            @DisplayName("When they do not contain the same integers (with custom error message)")
            void whenTheyDoNotContainSameIntegersWithCustomErrorMessage() {
                assertThat(ACTUAL)
                        .overridingErrorMessage(
                                "Expected arrays to not be equal but both are: %s",
                                Arrays.toString(EXPECTED)
                        )
                        .isNotEqualTo(EXPECTED);
            }
        }
 
        @Nested
        @DisplayName("When arrays contain strings as values")
        class WhenArraysContainStringValues {
 
            final String[] ACTUAL = new String[] {"Monica", "Geller"};
            final String[] EXPECTED = new String[] {"Ross", "Geller"};
 
            @Test
            @DisplayName("Should not contain the same string values")
            void notHavingSameStrings() {
                assertThat(ACTUAL).isNotEqualTo(EXPECTED);
            }
 
            @Test
            @DisplayName("Should not contain the same string values (with custom error message)")
            void notHavingSameStringsWithCustomErrorMessage() {
                assertThat(ACTUAL)
                        .overridingErrorMessage(
                                "Expected arrays to not be equal but both are: %s",
                                Arrays.toString(EXPECTED)
                        )
                        .isNotEqualTo(EXPECTED);
            }
        }
    }
}


When the test cases run we can see like below screenshot

 

So JUnit 5 helps to make test cases exclusive in this way. @DisplayName and @Nested are very helpful in creating them. Whenever there are errors, they can be easily noted below

 

Now let us see for List

ListAssertionSampleTest.java

Java




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;
 
// This class demonstrates how we can write
// assertions for {@code List} objects
// by using AssertJ
@DisplayName("List assertion writes sample tests")
class ListAssertionSampleTest {
 
    @Nested
    @DisplayName("When we write assertions for elements")
    class SampleAssertionsForElements {
 
        private final int EXPECTED_SIZE = 2;
        private Object firstObject;
        private Object secondObject;
        private List<Object> objectList;
 
        @BeforeEach
        void creationAndInitializationList() {
            firstObject = new Object();
            secondObject = new Object();
 
            objectList = Arrays.asList(firstObject, secondObject);
        }
 
        @Test
        @DisplayName("Checking for the list should contain two elements")
        void whenThereAreTwoElements() {
            assertThat(objectList).hasSize(EXPECTED_SIZE);
        }
 
        @Test
        @DisplayName("Checking for the list should contain two elements (with custom error message)")
        void whenThereAreTwoElementsWithCustomErrorMessage() {
            assertThat(objectList)
                    .overridingErrorMessage(
                            "Expected the size of the list to be: %d but it was: %d",
                            EXPECTED_SIZE,
                            objectList.size()
                    )
                    .hasSize(EXPECTED_SIZE);
        }
 
        @Test
        @DisplayName("When there are correct elements in given order")
        void whenThereAreCorrectElementsInGivenOrder() {
            assertThat(objectList).containsExactly(firstObject, secondObject);
        }
 
        @Test
        @DisplayName("When there are correct elements in given order (with custom error message)")
        void whenThereAreCorrectElementsInGivenOrderWithCustomErrorMessage() {
            assertThat(objectList)
                    .overridingErrorMessage(
                            "Expected the list to contain the objects: %s and %s but it contained: %s",
                            firstObject,
                            secondObject,
                            Arrays.toString(objectList.toArray())
                    )
                    .containsExactly(firstObject, secondObject);
        }
 
        @Test
        @DisplayName("When there are correct elements in any order")
        void whenThereAreCorrectElementsInAnyOrder() {
            assertThat(objectList).containsExactlyInAnyOrder(secondObject, firstObject);
        }
 
        @Test
        @DisplayName("When there are correct elements in any order (with custom error message)")
        void whenThereAreCorrectElementsInAnyOrderWithCustomErrorMessage() {
            assertThat(objectList)
                    .overridingErrorMessage(
                            "Expected the list to contain the objects: %s and %s in any order but it contained: %s",
                            secondObject,
                            firstObject,
                            Arrays.toString(objectList.toArray())
                    )
                    .containsExactlyInAnyOrder(secondObject, firstObject);
        }
 
        @Test
        @DisplayName("When there are correct elements present for once")
        void whenThereAreCorrectElementsOnce() {
            assertThat(objectList).containsOnlyOnce(firstObject);
        }
 
        @Test
        @DisplayName("When there are correct elements present for once (with custom error message)")
        void whenThereAreCorrectElementsWithCustomErrorMessage() {
            assertThat(objectList)
                    .overridingErrorMessage(
                            "Expected the list to contain the object: %s only",
                            firstObject
                    )
                    .containsOnlyOnce(firstObject);
        }
 
        @Test
        @DisplayName("Check that list should not contain an incorrect element")
        void whenNotContainIncorrectElement() {
            assertThat(objectList).doesNotContain(new Object());
        }
 
        @Test
        @DisplayName("Check that list should not contain an incorrect element (with custom error message)")
        void whenNotContainIncorrectElementWithCustomErrorMessage() {
            Object incorrect = new Object();
            assertThat(objectList)
                    .overridingErrorMessage(
                            "Expected the list to not contain the object: %s",
                            incorrect
                    )
                    .doesNotContain(new Object());
        }
    }
 
    @Nested
    @DisplayName("Comparison of two lists")
    class ComparisonOfTwoLists {
 
        private final List<Integer> FIRSTLIST = Arrays.asList(100, 200, 500);
        private final List<Integer> SECONDLIST = Arrays.asList(100, 200, 500);
 
        @Test
        @DisplayName("List should contain the same elements")
        void listShouldContainSameElements() {
            assertThat(FIRSTLIST).isEqualTo(SECONDLIST);
        }
 
        @Test
        @DisplayName("List Should contain the same elements (with custom error message)")
        void listShouldContainSameElementsWithCustomErrorMessage() {
            assertThat(FIRSTLIST)
                    .overridingErrorMessage(
                            "Expected the list to contain: %s but it contained: %s",
                            Arrays.toString(SECONDLIST.toArray()),
                            Arrays.toString(FIRSTLIST.toArray())
                    )
                    .isEqualTo(SECONDLIST);
        }
    }
}


When we run the tests,

 

Conclusion

JUnit test cases always help to improve the quality of software. That too with JUNIT5, additionally maintenance wise, friendly wise they can be easy to be written and maintained.

RELATED ARTICLES

Most Popular

Recent Comments