arekolek
arekolek

Reputation: 9611

Extracting field from both actual and expected objects when testing with AssertJ

I would like to check that a list contains a sub-list of another list. Here's a dummy example of how I do it currently:

@Test
public void testExtracting() throws Exception {
    final List<User> users = new ArrayList<>();
    users.add(new User(5234, "Adam"));
    users.add(new User(4635, "David"));

    final List<User> newUsers = new ArrayList<>();
    newUsers.add(new User(6143, "Bob"));
    newUsers.add(new User(3465, "Cindy"));

    users.addAll(newUsers);

    assertThat(users).extracting("id").contains(newUsers.get(0).id, newUsers.get(1).id);
}

public static class User {
    public long id;
    public String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Is it possible to achieve the same result in a more compact way, without overriding the equals method of User class? I'm looking for something along the lines of:

assertThat(users).contains(newUsers.get(0), newUsers.get(1)).extracting("id");

Or, better yet:

assertThat(users).contains(newUsers.subList(0, 2)).extracting("id");

Upvotes: 1

Views: 3785

Answers (2)

Emmanuel Essiennta
Emmanuel Essiennta

Reputation: 69

You can create a getter method for the id property and do this:

assertThat(users).usingElementComparator(Comparator.comparing(User::getId)).containsAll(newUsers);

Upvotes: 0

Todd
Todd

Reputation: 31690

If you are able to add a getId() method to User, you can solve this with an extractor:

assertThat(users)
    .extracting("id")
    .containsAll(extractProperty("id").from(newUsers));

Without being able to change User (so no overriding hashcode() or equals(), or adding getters), you will need to extract the id from both sets and compare them. This worked for me, but I'll admit it's a bit ugly.

assertThat(users)
    .extracting("id")
    .containsAll(newUsers.stream().map(it -> it.id).collect(Collectors.toSet()));

What I'm doing is using assertJ to extract the id from the users set and Java 8 streams/map to get all the newUser ids in one collection. This way your newUsers collection can be arbitrarily large and you don't have to hard code the mapping yourself.

Note that the stream/map work in the second example is the same work being done in the first example by extractProperty, we're just doing it manually.

Upvotes: 5

Related Questions