When programming in Java, you often end up writing methods returning a collection of objects. They certainly have their place in your application, but testing them can be a little tricky. Depending on the implementation of the underlying collection, the order of the elements may be different, the
equals on collections is not always obvious, and so on. I have come across multiple examples of such cases in my career, and I decided to pick a couple of them and show a way to tackle them with AssertJ, the assertions library you should definitely be using.
All the recipes follow the same format. I present a short description, followed by the implementation of the test. The test is always successful, to avoid confusion. Each recipe ends with a short remark, like what other situations can this be used for. I’m also using the Guava library to create the collections, as vanilla Java doesn’t really provide a way to do that.
We could use some Java primitives like
int for the sake of the tests, but in the wild, this is not seen very often. Let’s say we’re making an RPG game, so we’re going to have a lot of POJOs, representing different characters and objects in the game. For example, a class representing a monster:
The code for both the model and the tests is available as a gist.
Collection Contains an Expected Element
Let’s kick off with the simplest one. You want to be sure that the list returning from one method contains an element (or elements) that is interesting to you. AssertJ allows you to achieve that with the
contains method and its negative counterpart
doesNotContain. The method checks whether the given elements are in the collection:
The first two lines check that
werewolf belong to the
beasts collection. As you can see in the next line, you can also verify multiple elements.
One thing to remember is that the method cares neither about all the elements (i.e. it doesn’t check whether there are other elements too) nor about the order.
Collection Contains All the Elements I Am Interested in, No Matter the Order
When generating collections, it’s pretty often that you don’t care about the order of the elements. This is where
containsExactlyInAnyOrder is useful:
This assumes that the count of the elements is exactly the same, but the order doesn’t play any role. You can achieve a similar goal using
containsExactlyElementsOf, which takes an
Iterable, but it’s not as elegant.
Collection Contains All the Elements I Am Interested in, in a Given Order
This is similar to the previous one, but without
Collection Contains Only the Given Elements
This sounds similar to the first one, but there’s a little twist: We don’t care about the counts, we only care if there are other elements:
This can be useful, for example, for a collection of enumerations that potentially can be repeated multiple times. Remember, this doesn’t check any order!
Collection With Elements Appearing Only Once
This sounds similar to the previous one. Even the method is named similarly:
containsOnlyOnce. The idea behind it is very different, though. While
containsOnly checks whether there are no other elements in the collection, this one checks that the given element exists in the collection (just like
contains), and it appears exactly once:
It sounds like a good idea to have a method that allows you to verify more complex counts, but unfortunately, at the moment of writing this post, there is no such method.
Collection of Elements With Given Properties
Now, here's something cool (it’s cool because I wrote that). When you want to check that the collection contains the elements that have a given property set to an expected value, you can use the
extracting method. With Java 8 lambda functions, it greatly increases readability:
A supplemental method is
flatExtracting. It is used for properties that return
List, and actually merges the lists from the properties.
The recipes described above are the most common use cases for writing tests of methods that return collections. If you feel that I am missing something, please let me know!