1
+ package com .bobocode .se ;
2
+
3
+ import static org .assertj .core .api .AssertionsForClassTypes .assertThat ;
4
+ import static org .junit .jupiter .api .Assertions .assertEquals ;
5
+ import static org .junit .jupiter .api .Assertions .assertThrows ;
6
+
7
+ import java .lang .reflect .Field ;
8
+ import java .util .Arrays ;
9
+ import lombok .AllArgsConstructor ;
10
+ import lombok .NoArgsConstructor ;
11
+ import lombok .SneakyThrows ;
12
+ import org .junit .jupiter .api .DisplayName ;
13
+ import org .junit .jupiter .api .MethodOrderer .OrderAnnotation ;
14
+ import org .junit .jupiter .api .Order ;
15
+ import org .junit .jupiter .api .Test ;
16
+ import org .junit .jupiter .api .TestMethodOrder ;
17
+
18
+ @ TestMethodOrder (OrderAnnotation .class )
19
+ class RandomFieldComparatorTest {
20
+
21
+ private final RandomFieldComparator <Account > randomFieldComparator = new RandomFieldComparator <>(Account .class );
22
+
23
+ @ Test
24
+ @ Order (1 )
25
+ @ DisplayName ("Constructor throws an exception when parameter is null" )
26
+ void classDoesNotApplyNullInConstructor () {
27
+ assertThrows (NullPointerException .class , () -> new RandomFieldComparator <>(null ));
28
+ }
29
+
30
+ @ Test
31
+ @ Order (2 )
32
+ @ SneakyThrows
33
+ @ DisplayName ("Constructor throws an exception when the target type has no Comparable fields" )
34
+ void constructorThrowsExceptionIfNoComparableFieldsInProvidedType () {
35
+ assertThrows (IllegalArgumentException .class , () -> new RandomFieldComparator <>(ClassWithNotComparableField .class ));
36
+ }
37
+
38
+ @ Test
39
+ @ Order (3 )
40
+ @ DisplayName ("Method 'compare' throws an exception when any parameter is null" )
41
+ void compareWhenFirstParameterAreNull () {
42
+
43
+ assertThrows (NullPointerException .class , () -> randomFieldComparator .compare (null , new Account ()));
44
+ assertThrows (NullPointerException .class , () -> randomFieldComparator .compare (new Account (), null ));
45
+ }
46
+
47
+ @ Test
48
+ @ Order (4 )
49
+ @ DisplayName ("Method 'compare' returns 0 when field values of both objects are null" )
50
+ void compareWhenBothFieldValuesIsNull () {
51
+ setFieldToCompare ("lastName" , Account .class );
52
+ int compareResult = randomFieldComparator .compare (new Account (), new Account ());
53
+
54
+ assertThat (compareResult ).isZero ();
55
+ }
56
+
57
+ @ Test
58
+ @ Order (5 )
59
+ @ DisplayName ("Method compare returns positive int when the first field value is null" )
60
+ void compareWhenFieldValuesOfFirstObjectIsNull () {
61
+ Account emptyAccount = new Account ();
62
+ Account account =
new Account (
"Sibma" ,
"LoinKing" ,
"[email protected] " ,
14 );
63
+ setFieldToCompare ("email" , Account .class );//set field to compare explicitly as there are int field which has default value 0
64
+ int compareResult = randomFieldComparator .compare (emptyAccount , account );
65
+
66
+ assertThat (compareResult ).isPositive ();
67
+ }
68
+
69
+ @ Test
70
+ @ Order (6 )
71
+ @ DisplayName ("Method compare returns negative int when the second field value is null" )
72
+ void compareWhenFieldValuesOfSecondObjectIsNull () {
73
+ Account account =
new Account (
"Mufasa" ,
"LoinKing" ,
"[email protected] " ,
47 );
74
+ Account emptyAccount = new Account ();
75
+ setFieldToCompare ("firstName" , Account .class );
76
+ int compareResult = randomFieldComparator .compare (account , emptyAccount );
77
+
78
+ assertThat (compareResult ).isNegative ();
79
+ }
80
+
81
+ @ Test
82
+ @ Order (7 )
83
+ @ SneakyThrows
84
+ @ DisplayName ("Method 'compare' returns positive int when the first value is greater" )
85
+ void compareWhenFieldValueOfFirstObjectIsGreater () {
86
+ var fieldToCompareName = "firstName" ;
87
+ Account account1 = new Account ();
88
+ Account account2 = new Account ();
89
+ Field fieldToCompareAccount = account1 .getClass ().getDeclaredField (fieldToCompareName );
90
+ fieldToCompareAccount .setAccessible (true );
91
+
92
+ fieldToCompareAccount .set (account1 , "Bob" );
93
+ fieldToCompareAccount .set (account2 , "Alice" );
94
+
95
+ setFieldToCompare (fieldToCompareName , Account .class );
96
+ int compareResult = randomFieldComparator .compare (account1 , account2 );
97
+
98
+ assertThat (compareResult ).isPositive ();
99
+ }
100
+
101
+ @ Test
102
+ @ Order (8 )
103
+ @ SneakyThrows
104
+ @ DisplayName ("Method 'compare' returns negative int when the first value is smaller" )
105
+ void compareWhenFieldValueOfSecondObjectIsGreater () {
106
+ var fieldToCompareName = "firstName" ;
107
+ Account account1 = new Account ();
108
+ Account account2 = new Account ();
109
+ Field fieldToCompareAccount = account1 .getClass ().getDeclaredField (fieldToCompareName );
110
+ fieldToCompareAccount .setAccessible (true );
111
+
112
+ fieldToCompareAccount .set (account1 , "Alice" );
113
+ fieldToCompareAccount .set (account2 , "Bob" );
114
+
115
+ setFieldToCompare (fieldToCompareName , Account .class );
116
+ int compareResult = randomFieldComparator .compare (account1 , account2 );
117
+
118
+ assertThat (compareResult ).isNegative ();
119
+ }
120
+
121
+ @ Test
122
+ @ Order (9 )
123
+ @ SneakyThrows
124
+ @ DisplayName ("Method 'compare' returns zero when the field values are equal" )
125
+ void compareWhenFieldValuesOfObjectsAreEqual () {
126
+ var fieldToCompareName = "firstName" ;
127
+ Account account1 = new Account ();
128
+ Account account2 = new Account ();
129
+ Field fieldToCompareAccount = account1 .getClass ().getDeclaredField (fieldToCompareName );
130
+ fieldToCompareAccount .setAccessible (true );
131
+
132
+ fieldToCompareAccount .set (account1 , "Carol" );
133
+ fieldToCompareAccount .set (account2 , "Carol" );
134
+
135
+ setFieldToCompare (fieldToCompareName , Account .class );
136
+ int compareResult = randomFieldComparator .compare (account1 , account2 );
137
+
138
+ assertThat (compareResult ).isZero ();
139
+ }
140
+
141
+ @ Test
142
+ @ Order (10 )
143
+ @ SneakyThrows
144
+ @ DisplayName ("Method 'compare' returns positive int when the first primitive value is greater" )
145
+ void comparePrimitivesWhenFieldValueOfFirstObjectIsGreater () {
146
+ var fieldToCompareName = "age" ;
147
+ Account account1 = new Account ();
148
+ Account account2 = new Account ();
149
+ Field fieldToCompareAccount = account1 .getClass ().getDeclaredField (fieldToCompareName );
150
+ fieldToCompareAccount .setAccessible (true );
151
+
152
+ fieldToCompareAccount .setInt (account1 , 7 );
153
+ fieldToCompareAccount .setInt (account2 , 3 );
154
+
155
+ setFieldToCompare (fieldToCompareName , Account .class );
156
+ int compareResult = randomFieldComparator .compare (account1 , account2 );
157
+
158
+ assertThat (compareResult ).isPositive ();
159
+ }
160
+
161
+ @ Test
162
+ @ Order (11 )
163
+ @ SneakyThrows
164
+ @ DisplayName ("Method 'compare' returns zero when the primitive field values are equal" )
165
+ void comparePrimitivesWhenFieldValuesOfObjectsAreEqual () {
166
+ var fieldToCompareName = "age" ;
167
+ Account account1 = new Account ();
168
+ Account account2 = new Account ();
169
+ Field fieldToCompareAccount = account1 .getClass ().getDeclaredField (fieldToCompareName );
170
+ fieldToCompareAccount .setAccessible (true );
171
+
172
+ fieldToCompareAccount .setInt (account1 , 15 );
173
+ fieldToCompareAccount .setInt (account2 , 15 );
174
+
175
+ setFieldToCompare (fieldToCompareName , Account .class );
176
+ int compareResult = randomFieldComparator .compare (account1 , account2 );
177
+
178
+ assertThat (compareResult ).isZero ();
179
+ }
180
+
181
+ @ Test
182
+ @ Order (12 )
183
+ @ SneakyThrows
184
+ @ DisplayName ("Method 'compare' returns negative int when the first primitive value is smaller" )
185
+ void comparePrimitivesWhenFieldValueOfSecondObjectIsGreater () {
186
+ var fieldToCompareName = "age" ;
187
+ Account account1 = new Account ();
188
+ Account account2 = new Account ();
189
+ Field fieldToCompareAccount = account1 .getClass ().getDeclaredField (fieldToCompareName );
190
+ fieldToCompareAccount .setAccessible (true );
191
+
192
+ fieldToCompareAccount .setInt (account1 , 4 );
193
+ fieldToCompareAccount .setInt (account2 , 8 );
194
+
195
+ setFieldToCompare (fieldToCompareName , Account .class );
196
+ int compareResult = randomFieldComparator .compare (account1 , account2 );
197
+
198
+ assertThat (compareResult ).isNegative ();
199
+ }
200
+
201
+ @ Test
202
+ @ Order (13 )
203
+ @ SneakyThrows
204
+ @ DisplayName ("Method 'getComparingFieldName' returns the name of randomly-chosen field to be compared" )
205
+ void getComparingFieldName () {
206
+ var fieldToCompareName = "lastName" ;
207
+ setFieldToCompare (fieldToCompareName , Account .class );
208
+
209
+ assertEquals (fieldToCompareName , randomFieldComparator .getComparingFieldName ());
210
+ }
211
+
212
+ @ Test
213
+ @ Order (14 )
214
+ @ SneakyThrows
215
+ @ DisplayName ("Method toString is properly overridden" )
216
+ void toStringOverriding () {
217
+ var expectedString = "Random field comparator of class 'Account' is comparing 'email'" ;
218
+ var fieldToCompareName = "email" ;
219
+ setFieldToCompare (fieldToCompareName , Account .class );
220
+
221
+ assertEquals (expectedString , randomFieldComparator .toString ());
222
+ }
223
+
224
+ @ SneakyThrows
225
+ private <T > void setFieldToCompare (String fieldName , Class <T > classType ) {
226
+ Field fieldToCompare = Arrays .stream (randomFieldComparator .getClass ().getDeclaredFields ())
227
+ .filter (f -> f .getType ().equals (Field .class ))
228
+ .findAny ()
229
+ .orElseThrow ();
230
+ fieldToCompare .setAccessible (true );
231
+ fieldToCompare .set (randomFieldComparator , classType .getDeclaredField (fieldName ));
232
+ }
233
+
234
+ private static class EmptyClass {
235
+
236
+ }
237
+
238
+ @ AllArgsConstructor
239
+ private static class ClassWithNotComparableField {
240
+
241
+ private Object field ;
242
+ }
243
+
244
+ @ NoArgsConstructor
245
+ @ AllArgsConstructor
246
+ private static class Account {
247
+
248
+ private String firstName ;
249
+ private String lastName ;
250
+ private String email ;
251
+ private int age ;
252
+ }
253
+ }
0 commit comments