Over a million developers have joined DZone.

A new way of extracting values in AssertJ collections assertions

DZone's Guide to

A new way of extracting values in AssertJ collections assertions

· DevOps Zone
Free Resource

The DevOps Zone is brought to you in partnership with Sonatype Nexus. The Nexus Suite helps scale your DevOps delivery with continuous component intelligence integrated into development tools, including Eclipse, IntelliJ, Jenkins, Bamboo, SonarQube and more. Schedule a demo today

We've been using AssertJ  in Young Digital Planet in several Java projects already and we love it. It makes our tests much easier to write and read, mainly thanks to ease of writing custom assertions. The automatically generated assertions worked greatly as a basis for testing our domain classes, except for one problem. There often appears a need to assert a list of our entities by one of their field, and then continue on other assertions. The field usually is an enumerated value and looks like this:

public enum Gender {

public class Person {
    private final String name;
    private final Gender gender;

    // the constructor and (g|s)etters, etc.

Now, when you wanted to make some assertions on the Person instances, you had to extract values using extracting method. An example would look like this:

Person wilma, betty, pebbles, fred, barney, bambam;
List<Person> persons = Lists.newArrayList(wilma, betty, pebbles, fred, barney, bambam; // guava-style

assertThat(persons).extracting("gender").containsExactly(FEMALE, FEMALE, FEMALE, MALE, MALE, MALE);

Even though quite handy, extracting by property name sucks badly in terms of object-oriented design. The fundamental reason is that any change in the class Person would cause all the test cases to fail due to property of invalid name. While it does not require many changes when you have a couple of test cases, introducing the change in couple hundreds is hell.

You could always write your own assertions for each of the field, but it is a little overkill. Instead of that, I proposed a change in the AssertJ to appear in version 1.7.0. The change introduced a Single Abstract Method (SAM) interface Extractor (you could call it functional if you were using Java 8), which handles the extraction of required property, but also can do any other transformation that is required. Thanks to that there's no longer need to write a whole set of assertions, just a small class that extracts the tested property. Now, the previous example would look like this:

public class GenderExtractor implements Extractor<Person, Gender> {

    // do yourself some good and write a factory method
    private GenderExtractor() { }

    public static Extractor<Person, Gender> gender() {
        return new GenderExtractor();

    public Gender extract(Person input) {
        return input.getGender();

assertThat(persons).extracting(gender()).containsExactly(FEMALE, FEMALE, FEMALE, MALE, MALE, MALE);

Much prettier, isn't it? But wait, there's more! Since I've been playing a lot with functional stuff (namely Scala), I added one more method that's complementary to extracting, and it's calledflatExtracting. If you see the similiarity between extracting and functional map, then the flatExtracting should be clear to you. In case you do not see correspondence: the flatExtracting extracts lists using the Extractor implementations, and then concatenates the lists. Just look at the example:

public class ChildrenExtractor implements Extractor<Person, List<Person>> {
    // with a factory method    

    public List<Person> extract(Person input) {
        return input.getChildren();

assertThat(Lists.newArrayList(fred, barney)).flatExtracting(children()).contains(pebbles, bambam);

In case you used the old extracting, fear not! The old methods were left to ensure the backwards compatibility. The change was merged last week, so feel free to get the snapshot version of AssertJ and test the extracting. Also, there are some examples in the git repository here.

The DevOps Zone is brought to you in partnership with Sonatype Nexus. Use the Nexus Suite to automate your software supply chain and ensure you're using the highest quality open source components at every step of the development lifecycle. Get Nexus today


Published at DZone with permission of Mateusz Haligowski. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}