assertj / assertj/assertj

Non-informative output of `usingRecursiveComparison().isEqualTo()` for structure containing Set as a field

Open
#4,020 5 comments 0 reactions 0 assignees View on GitHub
theme: recursive comparison
Dominant language
Java
Stars
2.8k
Forks
788
Avg merge
14h 57m
Merged PRs (30d)
36

Description

**Describe the bug**

Having recursive comparison of structures that contain sets inside assertJ outputs message that doesn't contain any information about the exact field in *actual* object that is not equal to the corresponding *expected* one. It just outputs that two sets are different. Using a debugger I can see it in method that calls `addDifference()`, but why it doesn't appear in the error message as when the same error appears in list?

* assertj core version: 3.27.4
* java version: 17
* test framework version: junit 5.12.2
* os (if relevant): windows

**Test case reproducing the bug**

```java
public class TestAssertJ {

@Value(staticConstructor = "of")
private static class SubItem {
String name;
String description;
}

@Value(staticConstructor = "of")
private static class Item {
Integer i;
String s;
Set subItems;
}

@Data
private static class Dto {
private Set items;
}

@Test
void testRecursiveForSet() {
final var actual = new Dto();
actual.items = Set.of(
Item.of(1, "2", Set.of(SubItem.of("name", "description"))),
Item.of(3, "4", Set.of(SubItem.of("name", "description")))
);
final var expected = new Dto();
expected.items = Set.of(
Item.of(1, "2", Set.of(SubItem.of("name", "description"))),
Item.of(3, "4", Set.of(SubItem.of("name", "another description")))
);
assertThat(actual).usingRecursiveComparison().isEqualTo(expected);
}
}
```

Output is
```
field/property 'items' differ:
- actual value : [TestAssertJ.Item(i=1, s=2, subItems=[TestAssertJ.SubItem(name=name, description=description)]),
TestAssertJ.Item(i=3, s=4, subItems=[TestAssertJ.SubItem(name=name, description=description)])]
- expected value: [TestAssertJ.Item(i=1, s=2, subItems=[TestAssertJ.SubItem(name=name, description=description)]),
TestAssertJ.Item(i=3, s=4, subItems=[TestAssertJ.SubItem(name=name, description=another description)])]
The following expected elements were not matched in the actual Set12:
[TestAssertJ.Item(i=3, s=4, subItems=[TestAssertJ.SubItem(name=name, description=another description)])]
```

If you change all Set to List you'll get more informative message:
```
field/property 'items[1].subItems[0].description' differ:
- actual value : "description"
- expected value: "another description"
```

Contributor guide

Open the contributing guide

Research direction

Start by running the reproducing test method testRecursiveForSet with the supplied AssertJ 3.27.4 example and compare its Set output with the List output. Trace the recursive comparison path that records differences for nested Set fields; done means the failure identifies the nested field and values, as in the list case.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.