Authors Top

We’re starting a new Scala area. If you have a few years of experience in the Scala ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Introduction

ScalaTest is one of the most popular testing libraries in Scala. ScalaTest matchers provide many easy-to-use and powerful ways to verify the results. In this tutorial, we’ll look at different ways to compare collection contents using ScalaTest.

2. Set-Up

Let’s first add the ScalaTest dependency to our build.sbt file:

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.11" % Test

3. Comparing Collection Contents

Let’s start by looking at different ways to compare the collection contents using ScalaTest. These approaches are similar for different types like List, Seq, Set, etc. For this tutorial, we’ll be using the AnyFlatSpec suite along with Should matchers.

3.1. Check for Exactness

To check if two collections contain exact elements in the same order, we can use the shouldBe method:

val intList = List(1, 2, 3, 4)
val expected = List(1, 2, 3, 4)
intList shouldBe expected

If the order of elements is not the same, the test will fail. This will work the same for a list of case class objects as well:

case class Country(name:String, code:String)
val countries = List(Country("Germany", "DE"), Country("India", "IN"))
val expected = List(Country("Germany", "DE"), Country("India", "IN"))
countries shouldBe expected

3.2. Check for the Same Elements

We can check if two collections contain the same elements in any order using the method theSameElementsAs:

val cities = List("Barcelona", "Hamburg")
val cities2 = List("Barcelona", "Hamburg")
Random.shuffle(cities) should contain theSameElementsAs (cities2)

However, it will fail if there are more elements in one of the collections, even if it is a duplicate element. In such cases, we’ll use the only method to ignore duplicate elements while comparing:

val cities = List("Barcelona", "Hamburg")
val cities2 = cities ++ cities
cities should contain only (cities2: _*)

The only() method expects the parameters as a variable argument. Therefore, we’re converting the list cities2 using :_*, also known as the splat operator.

3.3. Check for the Elements in the Same Order

The theSameElementsAs method will not consider the order of elements. If the ordering of the elements in the collection is important, we can use theSameElementsInOrderAs instead:

val cities = List("Barcelona", "Hamburg") 
val cities2 = List("Barcelona", "Hamburg") 
cities should contain theSameElementsInOrderAs (cities2)

3.4. At Least One Element Overlap

There are scenarios where we need to check if there is at least one element overlap between two collections. We can use the atLeastOneElementOf method to handle such scenarios:

val capitalCities = List("Berlin", "Paris", "Brussels", "Bern")
val cities = List("Zurich", "Geneva", "Munich", "Paris")
capitalCities should contain atLeastOneElementOf (cities)

3.5. At Most One Element Overlap

We can also check if two collections have an overlap of a maximum of one element using the atMostOneElementOf method:

val capitalCities = List("Berlin", "Paris", "Brussels", "Bern")
val cities = List("Zurich", "Geneva", "Munich", "Paris")
capitalCities should contain atMostOneElementOf (cities)

3.6. No Element Overlap

To check if there is no overlap between two collections, we can make use of the method noElementsOf and noneOf:

val cities = List("Barcelona", "Hamburg", "Amsterdam")
val scandinavian = List("Oslo", "Stockholm", "Copenhagen")
cities should contain noneOf ("Oslo", "Stockholm", "Copenhagen")
cities should contain noElementsOf (scandinavian)

The method noElementsOf expects a collection as a parameter, whereas noneOf expects a varargs parameter.

3.7. Exactly One Element Overlap

To check for exactly one element overlap we can use the oneOf method:

val asianCountries = List("india", "china", "russia")
asianCountries should contain oneOf ("germany", "italy", "russia")

4. Map Key and Value Verification

Additionally, ScalaTest provides matchers for checking keys and values in Map types.

4.1. Check if Key Exists in a Map

We can check if a Map contains a particular key:

val capitalMap = Map("India" -> "New Delhi", "Germany" -> "Berlin", "France" -> "Paris")
capitalMap should contain key "India"

Additionally, we can combine the keyword not to check for non-availability of a key as:

capitalMap should not contain key ("USA")

4.2. Check if Value Exists in a Map

To check if the Map contains a particular value, we can use:

val capitalMap = Map("India" -> "New Delhi", "Germany" -> "Berlin", "France" -> "Paris")
capitalMap should contain value "Berlin"

Similarly, we can add the keyword not to verify if a value is missing in the Map:

capitalMap should not contain value ("Munich")

5. Conclusion

In this tutorial, we looked at some different ways in which we can verify collection elements using ScalaTest. As always, the code samples used in this tutorial are available over on GitHub.

Authors Bottom

We’re starting a new Scala area. If you have a few years of experience in the Scala ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!