12

Given the following (quick and missing) code:

class Pair{
int x;
int y;
}

List l1 = Arrays.asList(new Match(1,2), new Match(1,3), new Match(2,3));
List l2 = Arrays.asList(new Match(1,2), new Match(1,3), new Match(2,3));

How can I compare the content of the lists? Everything I used so far checked if the objects themselves were equal and not the objects value:

assertThat(l1).isEqualTo(l2);
assertThat(l1).containsAll(l2);
assertThat(l1).containsExactly(values);
assertThat(l1).containsExactlyElementsOf(iterable);

Must I implement equals() method for Match class?

May this be the correct way?

for (int i = 0; i < l1.size(); i++){
    assertThat(l1.get(i)).usingRecursiveComparison().isEqualTol2.get(i));
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
dushkin
  • 1,939
  • 3
  • 37
  • 82

5 Answers5

14

Give a try to usingRecursiveFieldByFieldElementComparator(recursiveConfiguration), it enables recursive comparison to all iterable assertions.

Ex:

public class Person {
  String name;
  boolean hasPhd;
}

public class Doctor {
  String name;
  boolean hasPhd;
}

Doctor drSheldon = new Doctor("Sheldon Cooper", true);
Doctor drLeonard = new Doctor("Leonard Hofstadter", true);
Doctor drRaj = new Doctor("Raj Koothrappali", true);

Person sheldon = new Person("Sheldon Cooper", false);
Person leonard = new Person("Leonard Hofstadter", false);
Person raj = new Person("Raj Koothrappali", false);
Person howard = new Person("Howard Wolowitz", false);

List<Doctor> doctors = list(drSheldon, drLeonard, drRaj);
List<Person> people = list(sheldon, leonard, raj);

RecursiveComparisonConfiguration configuration = RecursiveComparisonConfiguration.builder()
                                                                                 .withIgnoredFields("hasPhd")
                                                                                 .build();

// assertion succeeds as both lists contains equivalent items in order.
assertThat(doctors).usingRecursiveFieldByFieldElementComparator(configuration)
                   .contains(sheldon);

See https://assertj.github.io/doc/#assertj-core-recursive-comparison-for-iterable for a more detailed explanation.

Joel Costigliola
  • 6,308
  • 27
  • 35
6

You should override equals() and hashCode()

Nimantha
  • 6,405
  • 6
  • 28
  • 69
vincendep
  • 528
  • 4
  • 10
  • 1
    That's correct. See the javadoc of equals() and hashCode() : https://docs.oracle.com/javase/6/docs/api/java/lang/Object.html – pyb Oct 23 '20 at 21:33
2

Yes, so after further researching I would recommend:

for (int i = 0; i < l1.size(); i++){
    assertThat(l1.get(i)).usingRecursiveComparison().isEqualTol2.get(i));
}

You can read the details:

https://assertj.github.io/doc/#assertj-core-recursive-comparison

Nimantha
  • 6,405
  • 6
  • 28
  • 69
dushkin
  • 1,939
  • 3
  • 37
  • 82
1

Using AssertJ:

assertThat(actualModel)
                    .usingRecursiveComparison()
                    ...variousOtherOptions()
                    .isEqualTo(expectedModel);

0

@vincentdep is correct. If you are using Java 14 or above, you can use a record class:

public record Pair(int x, int y){};

List l1 = Arrays.asList(new Pair(1,2), new Pair(1,3), new Pair(2,3));
List l2 = Arrays.asList(new Pair(1,2), new Pair(1,3), new Pair(2,3));

assertThat(l1).isEqualTo(l2);
assertThat(l1).containsAll(l2);
pyb
  • 4,813
  • 2
  • 27
  • 45
  • Thanks! I am using Java 11. – dushkin Oct 23 '20 at 21:35
  • I suggest trying the latest versions, it's fun! If you cannot, you have to override equals and hashCode or use a library to do it for you. Project Lombok would generate them while Apache Commons provides methods you can call. – pyb Oct 24 '20 at 00:05