1212 */
1313package org .assertj .core .api .recursive .comparison ;
1414
15+ import static java .lang .String .format ;
1516import static org .assertj .core .api .Assertions .assertThat ;
1617import static org .assertj .core .api .BDDAssertions .then ;
18+ import static org .assertj .core .util .Arrays .array ;
1719import static org .assertj .core .util .AssertionsUtil .expectAssertionError ;
20+ import static org .assertj .core .util .Lists .list ;
21+ import static org .assertj .core .util .Maps .newHashMap ;
1822import static org .junit .jupiter .params .provider .Arguments .arguments ;
1923
2024import java .util .Objects ;
3337public class RecursiveComparisonAssert_isEqualTo_usingOverriddenEquals_Test
3438 extends RecursiveComparisonAssert_isEqualTo_BaseTest implements PersonData {
3539
40+ @ ParameterizedTest (name = "{2}: actual={0} / expected={1}" )
41+ @ MethodSource
42+ void should_pass_when_using_overridden_equals (Object actual , Object expected , String testDescription ) {
43+ then (actual ).usingRecursiveComparison ()
44+ .usingOverriddenEquals ()
45+ .isEqualTo (expected );
46+ }
47+
48+ private static Stream <Arguments > should_pass_when_using_overridden_equals () {
49+ Person neighbourJohn = new Person ();
50+ neighbourJohn .neighbour = new AlwaysEqualPerson ("John" );
51+ Person neighbourJack = new Person ();
52+ neighbourJack .neighbour = new AlwaysEqualPerson ("Jack" );
53+
54+ WithObject withPerson1 = new WithObject (new PersonComparedByName ("John" , "green" , new Pet ("Ducky" , "Duck" )));
55+ WithObject withPerson2 = new WithObject (new PersonComparedByName ("John" , "blue" , new Pet ("Mia" , "Duck" )));
56+
57+ NeverEquals neverEquals1 = new NeverEquals (new PersonComparedByName ("John" , "green" , null ));
58+ NeverEquals neverEquals2 = new NeverEquals (new PersonComparedByName ("John" , "red" , new Pet ("Mia" , "Duck" )));
59+
60+ return Stream .of (arguments (withPerson1 , withPerson2 ,
61+ "different pets and colors but equals ignore them" ),
62+ arguments (list (withPerson1 ), list (withPerson2 ),
63+ "list: different pets and colors but equals ignore them" ),
64+ arguments (array (withPerson1 ), array (withPerson2 ),
65+ "array: different pets and colors but equals ignore them" ),
66+ arguments (newHashMap ("person" , withPerson1 ), newHashMap ("person" , withPerson2 ),
67+ "maps: different pets and colors but equals ignore them" ),
68+ arguments (Optional .of (withPerson1 ), Optional .of (withPerson2 ),
69+ "Optional: different pets and colors but equals ignore them" ),
70+ arguments (neighbourJohn , neighbourJack ,
71+ "neighbour type equals is always true" ),
72+ arguments (neverEquals1 , neverEquals2 ,
73+ "root objects are never compared with equals, their fields are" ));
74+ }
75+
3676 @ ParameterizedTest (name = "{2}: actual={0} / expected={1}" )
3777 @ MethodSource
3878 void should_fail_when_using_overridden_equals (Object actual , Object expected , String testDescription ) {
@@ -45,61 +85,38 @@ void should_fail_when_using_overridden_equals(Object actual, Object expected, St
4585 }
4686
4787 private static Stream <Arguments > should_fail_when_using_overridden_equals () {
48- Person person1 = new AlwaysDifferentPerson ();
49- person1 .neighbour = new Person ("John" );
50- Person person2 = new AlwaysDifferentPerson ();
51- person2 .neighbour = new Person ("John" );
52-
53- Person person3 = new Person ();
54- person3 .neighbour = new AlwaysDifferentPerson ();
55- person3 .neighbour .name = "John" ;
56- Person person4 = new Person ();
57- person4 .neighbour = new AlwaysDifferentPerson ();
58- person4 .neighbour .name = "John" ;
59-
60- return Stream .of (arguments (person1 , person2 , "root Person is AlwaysDifferentPerson" ),
61- arguments (person3 , person4 , "neighbour Person is AlwaysDifferentPerson" ));
62- }
63-
64- @ ParameterizedTest (name = "{2}: actual={0} / expected={1}" )
65- @ MethodSource
66- void should_pass_when_using_overridden_equals (Object actual , Object expected , String testDescription ) {
67- then (actual ).usingRecursiveComparison ()
68- .usingOverriddenEquals ()
69- .isEqualTo (expected );
88+ Person neighbourJohn = new Person ();
89+ neighbourJohn .neighbour = new AlwaysDifferentPerson ();
90+ neighbourJohn .neighbour .name = "John" ;
91+ Person differentNeighbourJohn = new Person ();
92+ differentNeighbourJohn .neighbour = new AlwaysDifferentPerson ();
93+ differentNeighbourJohn .neighbour .name = "John" ;
94+ return Stream .of (arguments (neighbourJohn , differentNeighbourJohn ,
95+ "neighbour type is AlwaysDifferentPerson" ),
96+ arguments (list (neighbourJohn ), list (differentNeighbourJohn ),
97+ "list: neighbour type is AlwaysDifferentPerson" ),
98+ arguments (array (neighbourJohn ), array (differentNeighbourJohn ),
99+ "array: neighbour type is AlwaysDifferentPerson" ),
100+ arguments (newHashMap ("person" , neighbourJohn ), newHashMap ("person" , differentNeighbourJohn ),
101+ "maps: neighbour type is AlwaysDifferentPerson" ),
102+ arguments (Optional .of (neighbourJohn ), Optional .of (differentNeighbourJohn ),
103+ "Optional: neighbour type is AlwaysDifferentPerson" ));
70104 }
71105
72- private static Stream <Arguments > should_pass_when_using_overridden_equals () {
73- Person person1 = new AlwaysEqualPerson ();
74- person1 .neighbour = new Person ("John" );
75- Person person2 = new AlwaysEqualPerson ();
76- person2 .neighbour = new Person ("Jack" );
77-
78- Person person3 = new Person ();
79- person3 .neighbour = new AlwaysEqualPerson ();
80- person3 .neighbour .name = "John" ;
81- Person person4 = new Person ();
82- person4 .neighbour = new AlwaysEqualPerson ();
83- person4 .neighbour .name = "Jack" ;
84-
85- return Stream .of (arguments (person1 , person2 , "root Person is AlwaysEqualPerson" ),
86- arguments (person3 , person4 , "neighbour Person is AlwaysEqualPerson" ));
87- }
88-
89- static class PersonWithOverriddenEquals {
106+ static class PersonComparedByName {
90107 String name ;
91108 String color ;
92109 Pet pet ;
93110
94- public PersonWithOverriddenEquals (String name , String color , Pet pet ) {
111+ public PersonComparedByName (String name , String color , Pet pet ) {
95112 this .name = name ; // only name is used in equals
96113 this .color = color ;
97114 this .pet = pet ;
98115 }
99116
100117 @ Override
101118 public boolean equals (Object o ) {
102- PersonWithOverriddenEquals person = (PersonWithOverriddenEquals ) o ;
119+ PersonComparedByName person = (PersonComparedByName ) o ;
103120 return Objects .equals (name , person .name );
104121 }
105122
@@ -110,7 +127,7 @@ public int hashCode() {
110127
111128 @ Override
112129 public String toString () {
113- return String . format ("Person [name=%s, color=%s]" , name , color );
130+ return format ("Person [name=%s, color=%s]" , name , color );
114131 }
115132 }
116133
@@ -135,47 +152,93 @@ public int hashCode() {
135152 }
136153 }
137154
138- static class PersonWrapper {
139- PersonWithOverriddenEquals person ;
140-
141- public PersonWrapper (PersonWithOverriddenEquals person ) {
142- this .person = person ;
143- }
144-
145- }
146-
147155 @ Test
148- void should_pass_when_comparison_using_overriden_equals_on_root_objects () {
156+ void should_use_equals_on_compared_field_only () {
149157 // GIVEN
150- PersonWithOverriddenEquals person1 = new PersonWithOverriddenEquals ( "John" , "green " , new Pet ( "Ducky" , "Duck" ));
151- PersonWithOverriddenEquals person2 = new PersonWithOverriddenEquals ( "John" , "blue " , new Pet ( "Mia" , "Duck" ));
158+ WithObject actual = new WithObject ( new A ( "abc " , new NeverEquals ( "never" ), new AlwaysEquals ( "always" ) ));
159+ WithObject expected = new WithObject ( new A ( "abc " , new NeverEquals ( "never" ), new AlwaysEquals ( "always" ) ));
152160 // WHEN/THEN
153- then (person1 ).usingRecursiveComparison ()
154- .usingOverriddenEquals ()
155- .isEqualTo (person2 );
161+ then (actual ).usingRecursiveComparison ()
162+ .usingOverriddenEquals ()
163+ .comparingOnlyFields ("group.name" , "group.neverEquals.name" )
164+ .isEqualTo (expected );
156165 }
157166
158167 @ Test
159- void should_pass_when_comparison_using_overriden_equals_on_fields () {
168+ void should_fail_since_the_compared_field_equals_returns_false_even_if_the_outer_field_equals_returns_true () {
160169 // GIVEN
161- Optional <PersonWithOverriddenEquals > person1 = Optional .of (new PersonWithOverriddenEquals ("John" , "green" ,
162- new Pet ("Ducky" , "Duck" )));
163- Optional <PersonWithOverriddenEquals > person2 = Optional .of (new PersonWithOverriddenEquals ("John" , "green" ,
164- new Pet ("Mia" , "Duck" )));
165- // WHEN/THEN
166- then (person1 ).usingRecursiveComparison ()
167- .usingOverriddenEquals ()
168- .isEqualTo (person2 );
170+ WithObject actual = new WithObject (new A ("abc" , new NeverEquals ("never" ), new AlwaysEquals ("always" )));
171+ WithObject expected = new WithObject (new A ("abc" , new NeverEquals ("never" ), new AlwaysEquals ("always" )));
172+ // WHEN
173+ AssertionError assertionError = expectAssertionError (() -> assertThat (actual ).usingRecursiveComparison ()
174+ .usingOverriddenEquals ()
175+ .comparingOnlyFields ("group.name" ,
176+ "group.neverEquals" )
177+ .isEqualTo (expected ));
178+ // THEN
179+ then (assertionError ).hasMessageContaining ("- equals methods were used in the comparison" );
169180 }
170181
171- @ Test
172- void should_pass_when_comparison_using_overriden_equals_on_person_wrapper () {
173- // GIVEN
174- PersonWrapper person1 = new PersonWrapper (new PersonWithOverriddenEquals ("John" , "green" , new Pet ("Ducky" , "Duck" )));
175- PersonWrapper person2 = new PersonWrapper (new PersonWithOverriddenEquals ("John" , "green" , new Pet ("Mia" , "Duck" )));
176- // WHEN/THEN
177- then (person1 ).usingRecursiveComparison ()
178- .usingOverriddenEquals ()
179- .isEqualTo (person2 );
182+ private static class A {
183+ private final String name ;
184+ private final NeverEquals neverEquals ;
185+ private final AlwaysEquals alwaysEquals ;
186+
187+ public A (String name , NeverEquals neverEquals , AlwaysEquals alwaysEquals ) {
188+ this .name = name ;
189+ this .neverEquals = neverEquals ;
190+ this .alwaysEquals = alwaysEquals ;
191+ }
192+
193+ @ Override
194+ public boolean equals (Object o ) {
195+ if (this == o ) return true ;
196+ if (!(o instanceof A )) return false ;
197+ A a = (A ) o ;
198+ return Objects .equals (name , a .name )
199+ && Objects .equals (neverEquals , a .neverEquals )
200+ && Objects .equals (alwaysEquals , a .alwaysEquals );
201+ }
202+
203+ @ Override
204+ public String toString () {
205+ return format ("A[name=%s, neverEquals=%s, alwaysEquals=%s]" , this .name , this .neverEquals , this .alwaysEquals );
206+ }
207+ }
208+
209+ private static class NeverEquals {
210+ final Object name ;
211+
212+ public NeverEquals (Object name ) {
213+ this .name = name ;
214+ }
215+
216+ @ Override
217+ public boolean equals (Object o ) {
218+ return false ;
219+ }
220+
221+ @ Override
222+ public String toString () {
223+ return format ("NeverEquals[name=%s]" , this .name );
224+ }
225+ }
226+
227+ private static class AlwaysEquals {
228+ final Object name ;
229+
230+ public AlwaysEquals (Object name ) {
231+ this .name = name ;
232+ }
233+
234+ @ Override
235+ public boolean equals (Object o ) {
236+ return true ;
237+ }
238+
239+ @ Override
240+ public String toString () {
241+ return format ("AlwaysEquals[name=%s]" , this .name );
242+ }
180243 }
181244}
0 commit comments