assertj / Java comparing objects with list field ignoring order of elements in list
Asked Answered
R

2

12

I am looking to compare 2 list of objects (say Foo) in test.

List<Foo> fooA;
List<Foo> fooB;

Each Foo entry has one of the fields of type List (say Bar)

class Foo {
  private List<Bar> bars;
  ....
}

assertThat(fooA).isEqualTo(fooB);

Comparison fails because elements of bars are same but in different order.

Is there a way to compare them ignoring order?

I am not looking for below option.

assertThat(fooA).usingElementComparatorIgnoringFields("bars").isEqualTo(fooB);

Ideally I would like to compare all the fields

Rickrack answered 10/12, 2018 at 16:12 Comment(5)
The comparison would fail even if the items were in the same order because the 2 lists are 2 different objects.Infielder
See this other answerTolbert
Silly question: does Foo has an equals method defined?Dupondius
Foo has an equals method defined and it checks if 2 list fields are equal. I tried updating it to check for containsAll instead but that din't help.Rickrack
for groovy, use @EqualsAndHashCode. for java override equals/hashcodeLegation
S
13

you can do this with assertJ:

assertThat(fooA).usingRecursiveComparison().ignoringCollectionOrder().isEqualTo(fooB)
Soapstone answered 6/8, 2021 at 8:6 Comment(2)
Recursive comparison allows you to compare field by field recursively even if they were not of the same type.Mcavoy
This answer save my day on containsExactlyInAnyOrderElementsOf having list entry with OffsetDateTime with different offset issue that could be fixed with .usingRecursiveComparison().ignoringCollectionOrder().withComparatorForType(Comparator.comparing(a -> a.withOffsetSameInstant(ZoneOffset.UTC)),OffsetDateTime.class).isEqualTo(List.of(...Arenicolous
M
4

What you are looking for is containsExactlyInAnyOrderElementsOf(Iterable) defined in IterableAssert (emphasis is mine) :

Verifies that the actual group contains exactly the given values and nothing else, in any order.

You could write so :

List<Foo> fooA;
List<Foo> fooB;
//...
assertThat(fooA).containsExactlyInAnyOrderElementsOf(fooB);
Morin answered 10/12, 2018 at 16:23 Comment(1)
The question about comparing objects containing lists, not about comparing the lists themselvesGuerrilla

© 2022 - 2024 — McMap. All rights reserved.