Skip to content

Recursive comparison checks for existence of fields in types that parameterize nested unordered iterables #3332

@alexander-ly

Description

@alexander-ly

Describe the bug
When using usingRecursiveFieldByFieldElementComparatorOnFields to compare equality with objects that have nested unordered iterables, the comparison checks for existence of the fields to be compared inside of the class type parameter of the iterable.

  • assertj core version: 3.25.1
  • java version: 17
  • test framework version: JUnit 5
  • os (if relevant):

Test case reproducing the bug

@Test
void testRecursiveComparisonWithNestedIterable() {
    Collection<Name> names = new HashSet<>();
    names.add(new Name("john", "doe"));
    names.add(new Name("jane", "smith"));

    // List.copyOf passes test, Set.copyOf fails test
    Person actual = new Person(Set.copyOf(names));
    Person expected = new Person(Set.copyOf(names));

    assertThat(Set.of(actual))
            .usingRecursiveFieldByFieldElementComparatorOnFields("names")
            .containsExactlyInAnyOrder(expected);
}

class Person {
    Collection<Name> names;

    public Person(Collection<Name> names) {
        this.names = names;
    }
}

class Name {
    String first;
    String last;

    public Name(String first, String last) {
        this.first = first;
        this.last = last;
    }
}

/*
/* Stack trace
The following fields don't exist: {names}
java.lang.IllegalArgumentException: The following fields don't exist: {names}
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration.checkComparedFieldsExist(RecursiveComparisonConfiguration.java:1086)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator$ComparisonState.initDualValuesToCompare(RecursiveComparisonDifferenceCalculator.java:144)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator$ComparisonState.access$100(RecursiveComparisonDifferenceCalculator.java:73)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator.determineDifferences(RecursiveComparisonDifferenceCalculator.java:235)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator.searchIterableForElement(RecursiveComparisonDifferenceCalculator.java:599)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator.compareUnorderedIterables(RecursiveComparisonDifferenceCalculator.java:569)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator.determineDifferences(RecursiveComparisonDifferenceCalculator.java:313)
	at org.assertj.core.api.recursive.comparison.RecursiveComparisonDifferenceCalculator.determineDifferences(RecursiveComparisonDifferenceCalculator.java:226)
	at org.assertj.core.internal.ConfigurableRecursiveFieldByFieldComparator.areEqual(ConfigurableRecursiveFieldByFieldComparator.java:55)
	at org.assertj.core.internal.ConfigurableRecursiveFieldByFieldComparator.compare(ConfigurableRecursiveFieldByFieldComparator.java:50)
	at org.assertj.core.internal.ComparatorBasedComparisonStrategy.iterableContains(ComparatorBasedComparisonStrategy.java:91)
	at org.assertj.core.internal.Iterables.iterableContains(Iterables.java:367)
	at org.assertj.core.internal.Iterables.assertContainsExactlyInAnyOrder(Iterables.java:1402)
	at org.assertj.core.api.AbstractIterableAssert.containsExactlyInAnyOrderForProxy(AbstractIterableAssert.java:442)
	at org.assertj.core.api.AbstractIterableAssert.containsExactlyInAnyOrder(AbstractIterableAssert.java:435)
*/

Metadata

Metadata

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions