1. Introduction

While writing tests with Kotest, developers find the need to verify that a list of objects contains elements meeting specific expectations. This can even include checking for specific properties on the objects in the list.

In this tutorial, we’ll explore ways to validate that a list contains elements having specific properties.

2. Dependency

Before we get started, we’ll need to ensure we have the Kotest testing framework available in our project.

Kotest uses the JUnit Platform on the JVM. So, in a Maven project, we can include the runner and framework using this declaration in the pom.xml:

<dependency>
    <groupId>io.kotest</groupId>
    <artifactId>kotest-assertions-core-jvm</artifactId>
    <version>5.6.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.kotest</groupId>
    <artifactId>kotest-runner-junit5-jvm</artifactId>
    <version>5.6.2</version>
    <scope>test</scope>
</dependency>

3. Validating That a List Contains an Element with Specific Properties

Now, let’s dive straight into the subject matter of this article.

We’ll leverage Inspectors from Kotest’s assertion library. Inspectors allow us to test elements in a collection. They’re extension functions for Collections and Arrays that test if all, some, or none of the elements pass the given assertions.

There are many types of Inspectors in Kotest, and we’ll explore the ones that fit our use cases best.

For these examples, we’re going to consider two data classes, Pet and Car:

data class Pet(val owner: String, val color: String)
data class Car(val color: String, val owner: String)

In addition, we’ll be using these lists:

val cars = listOf(Car("Blue", "John"), Car("Red", "Peter"), Car("White", "James"))
val pets = listOf(Pet("James", "Yellow"), Pet("James", "White"), Pet("John", "Red"))

3.1. Using forAtLeastOne() and forAtLeast()

Now, let’s imagine a scenario where we want to assert that a list of cars contains an element with the same owner and color as a pet. We can use forAtLeastOne() to verify that at least one item in the collection satisfies our conditions:

val pet = Pet("James", "White")
cars.forAtLeastOne { car ->
    pet.owner shouldBe car.owner
    pet.color shouldBe car.color
}

Additionally, there’s another version called forAtLeast() that can receive the minimum number of items we expect to satisfy our conditions:

cars.forAtLeast(1) { car ->
    pet.owner shouldBe car.owner
    pet.color shouldBe car.color
}

3.2. Using forAtMost()

Now, suppose we want to assert that a list of pets contains at most two elements with the same owner as a car. We can use forAtMost() with an Int to describe the maximum number of items we expect to find that match our assertions:

val car = Car("Green", "James")
pets.forAtMost(2){pet ->
    pet.owner shouldBe car.owner
}

3.3. Using forNone()

We can use forNone() to assert that nothing matches our criteria in the list:

cars.forNone {car ->
    car.color shouldBe "Green"
}

3.4. Using forSome()

When we want to check if at least one, but not all items in the list match an expectation, we should use forSome(). This inspector asserts that between 1 and n-1 elements pass the expectations. If all items pass or none of the items pass, this assertion will fail.

So, let’s assert that some cars are owned by Peter:

cars.forSome { car ->
    car.owner shouldBe "Peter"
}

3.5. Using forExactly()

To check that a list contains a specific number of items that meet our expectations, we should use forExactly(). This inspector asserts that exactly the specified number of elements match. Now, let’s assert that James owns exactly two pets:

pets.forExactly(2) { pet ->
    pet.owner shouldBe "James"
}

3.6. Using forAll()

To make assertions about every item in the list, we should use forAll(). With this inspector, we can assert that every car owner’s name has at least three characters or every pet has an owner:

pets.forAll { pet ->
    pet.owner.shouldNotBeBlank()
}

cars.forAll { car ->
    car.owner.shouldHaveMinLength(3)
}

4. Conclusion

In this quick article, we’ve explored several Inspectors from the Kotest test framework and demonstrated how they could be used to validate that a collection contains elements with properties that satisfy particular conditions.

As always, the code samples and relevant test cases pertaining to this article can be found over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.