Java

Форк
0
/
EqualsTesterTest.java 
458 строк · 12.9 Кб
1
/*
2
 * Copyright (C) 2007 The Guava Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package com.google.common.testing;
18

19
import com.google.common.annotations.GwtCompatible;
20
import com.google.common.base.Preconditions;
21
import com.google.common.collect.ImmutableList;
22
import com.google.common.collect.Sets;
23
import java.util.Set;
24
import junit.framework.AssertionFailedError;
25
import junit.framework.TestCase;
26
import org.checkerframework.checker.nullness.qual.Nullable;
27

28
/**
29
 * Unit tests for {@link EqualsTester}.
30
 *
31
 * @author Jim McMaster
32
 */
33
@GwtCompatible
34
@SuppressWarnings("MissingTestCall")
35
public class EqualsTesterTest extends TestCase {
36
  private ValidTestObject reference;
37
  private EqualsTester equalsTester;
38
  private ValidTestObject equalObject1;
39
  private ValidTestObject equalObject2;
40
  private ValidTestObject notEqualObject1;
41

42
  @Override
43
  public void setUp() throws Exception {
44
    super.setUp();
45
    reference = new ValidTestObject(1, 2);
46
    equalsTester = new EqualsTester();
47
    equalObject1 = new ValidTestObject(1, 2);
48
    equalObject2 = new ValidTestObject(1, 2);
49
    notEqualObject1 = new ValidTestObject(0, 2);
50
  }
51

52
  /** Test null reference yields error */
53
  public void testAddNullReference() {
54
    try {
55
      equalsTester.addEqualityGroup((Object) null);
56
      fail("Should fail on null reference");
57
    } catch (NullPointerException e) {
58
    }
59
  }
60

61
  /** Test equalObjects after adding multiple instances at once with a null */
62
  public void testAddTwoEqualObjectsAtOnceWithNull() {
63
    try {
64
      equalsTester.addEqualityGroup(reference, equalObject1, null);
65
      fail("Should fail on null equal object");
66
    } catch (NullPointerException e) {
67
    }
68
  }
69

70
  /** Test adding null equal object yields error */
71
  public void testAddNullEqualObject() {
72
    try {
73
      equalsTester.addEqualityGroup(reference, (Object[]) null);
74
      fail("Should fail on null equal object");
75
    } catch (NullPointerException e) {
76
    }
77
  }
78

79
  /**
80
   * Test adding objects only by addEqualityGroup, with no reference object specified in the
81
   * constructor.
82
   */
83
  public void testAddEqualObjectWithOArgConstructor() {
84
    equalsTester.addEqualityGroup(equalObject1, notEqualObject1);
85
    try {
86
      equalsTester.testEquals();
87
    } catch (AssertionFailedError e) {
88
      assertErrorMessage(
89
          e,
90
          equalObject1
91
              + " [group 1, item 1] must be Object#equals to "
92
              + notEqualObject1
93
              + " [group 1, item 2]");
94
      return;
95
    }
96
    fail("Should get not equal to equal object error");
97
  }
98

99
  /**
100
   * Test EqualsTester with no equals or not equals objects. This checks proper handling of null,
101
   * incompatible class and reflexive tests
102
   */
103
  public void testTestEqualsEmptyLists() {
104
    equalsTester.addEqualityGroup(reference);
105
    equalsTester.testEquals();
106
  }
107

108
  /**
109
   * Test EqualsTester after populating equalObjects. This checks proper handling of equality and
110
   * verifies hashCode for valid objects
111
   */
112
  public void testTestEqualsEqualsObjects() {
113
    equalsTester.addEqualityGroup(reference, equalObject1, equalObject2);
114
    equalsTester.testEquals();
115
  }
116

117
  /** Test proper handling of case where an object is not equal to itself */
118
  public void testNonReflexiveEquals() {
119
    Object obj = new NonReflexiveObject();
120
    equalsTester.addEqualityGroup(obj);
121
    try {
122
      equalsTester.testEquals();
123
    } catch (AssertionFailedError e) {
124
      assertErrorMessage(e, obj + " must be Object#equals to itself");
125
      return;
126
    }
127
    fail("Should get non-reflexive error");
128
  }
129

130
  /** Test proper handling where an object tests equal to null */
131
  public void testInvalidEqualsNull() {
132
    Object obj = new InvalidEqualsNullObject();
133
    equalsTester.addEqualityGroup(obj);
134
    try {
135
      equalsTester.testEquals();
136
    } catch (AssertionFailedError e) {
137
      assertErrorMessage(e, obj + " must not be Object#equals to null");
138
      return;
139
    }
140
    fail("Should get equal to null error");
141
  }
142

143
  /** Test proper handling where an object incorrectly tests for an incompatible class */
144
  public void testInvalidEqualsIncompatibleClass() {
145
    Object obj = new InvalidEqualsIncompatibleClassObject();
146
    equalsTester.addEqualityGroup(obj);
147
    try {
148
      equalsTester.testEquals();
149
    } catch (AssertionFailedError e) {
150
      assertErrorMessage(
151
          e, obj + " must not be Object#equals to an arbitrary object of another class");
152
      return;
153
    }
154
    fail("Should get equal to incompatible class error");
155
  }
156

157
  /** Test proper handling where an object is not equal to one the user has said should be equal */
158
  public void testInvalidNotEqualsEqualObject() {
159
    equalsTester.addEqualityGroup(reference, notEqualObject1);
160
    try {
161
      equalsTester.testEquals();
162
    } catch (AssertionFailedError e) {
163
      assertErrorMessage(e, reference + " [group 1, item 1]");
164
      assertErrorMessage(e, notEqualObject1 + " [group 1, item 2]");
165
      return;
166
    }
167
    fail("Should get not equal to equal object error");
168
  }
169

170
  /**
171
   * Test for an invalid hashCode method, i.e., one that returns different value for objects that
172
   * are equal according to the equals method
173
   */
174
  public void testInvalidHashCode() {
175
    Object a = new InvalidHashCodeObject(1, 2);
176
    Object b = new InvalidHashCodeObject(1, 2);
177
    equalsTester.addEqualityGroup(a, b);
178
    try {
179
      equalsTester.testEquals();
180
    } catch (AssertionFailedError e) {
181
      assertErrorMessage(
182
          e,
183
          "the Object#hashCode ("
184
              + a.hashCode()
185
              + ") of "
186
              + a
187
              + " [group 1, item 1] must be equal to the Object#hashCode ("
188
              + b.hashCode()
189
              + ") of "
190
              + b);
191
      return;
192
    }
193
    fail("Should get invalid hashCode error");
194
  }
195

196
  public void testNullEqualityGroup() {
197
    EqualsTester tester = new EqualsTester();
198
    try {
199
      tester.addEqualityGroup((Object[]) null);
200
      fail();
201
    } catch (NullPointerException e) {
202
    }
203
  }
204

205
  public void testNullObjectInEqualityGroup() {
206
    EqualsTester tester = new EqualsTester();
207
    try {
208
      tester.addEqualityGroup(1, null, 3);
209
      fail();
210
    } catch (NullPointerException e) {
211
      assertErrorMessage(e, "at index 1");
212
    }
213
  }
214

215
  public void testSymmetryBroken() {
216
    EqualsTester tester =
217
        new EqualsTester().addEqualityGroup(named("foo").addPeers("bar"), named("bar"));
218
    try {
219
      tester.testEquals();
220
    } catch (AssertionFailedError e) {
221
      assertErrorMessage(e, "bar [group 1, item 2] must be Object#equals to foo [group 1, item 1]");
222
      return;
223
    }
224
    fail("should failed because symmetry is broken");
225
  }
226

227
  public void testTransitivityBrokenInEqualityGroup() {
228
    EqualsTester tester =
229
        new EqualsTester()
230
            .addEqualityGroup(
231
                named("foo").addPeers("bar", "baz"),
232
                named("bar").addPeers("foo"),
233
                named("baz").addPeers("foo"));
234
    try {
235
      tester.testEquals();
236
    } catch (AssertionFailedError e) {
237
      assertErrorMessage(e, "bar [group 1, item 2] must be Object#equals to baz [group 1, item 3]");
238
      return;
239
    }
240
    fail("should failed because transitivity is broken");
241
  }
242

243
  public void testUnequalObjectsInEqualityGroup() {
244
    EqualsTester tester = new EqualsTester().addEqualityGroup(named("foo"), named("bar"));
245
    try {
246
      tester.testEquals();
247
    } catch (AssertionFailedError e) {
248
      assertErrorMessage(e, "foo [group 1, item 1] must be Object#equals to bar [group 1, item 2]");
249
      return;
250
    }
251
    fail("should failed because of unequal objects in the same equality group");
252
  }
253

254
  public void testTransitivityBrokenAcrossEqualityGroups() {
255
    EqualsTester tester =
256
        new EqualsTester()
257
            .addEqualityGroup(named("foo").addPeers("bar"), named("bar").addPeers("foo", "x"))
258
            .addEqualityGroup(named("baz").addPeers("x"), named("x").addPeers("baz", "bar"));
259
    try {
260
      tester.testEquals();
261
    } catch (AssertionFailedError e) {
262
      assertErrorMessage(
263
          e, "bar [group 1, item 2] must not be Object#equals to x [group 2, item 2]");
264
      return;
265
    }
266
    fail("should failed because transitivity is broken");
267
  }
268

269
  public void testEqualityGroups() {
270
    new EqualsTester()
271
        .addEqualityGroup(named("foo").addPeers("bar"), named("bar").addPeers("foo"))
272
        .addEqualityGroup(named("baz"), named("baz"))
273
        .testEquals();
274
  }
275

276
  public void testEqualityBasedOnToString() {
277
    try {
278
      new EqualsTester().addEqualityGroup(new EqualsBasedOnToString("foo")).testEquals();
279
      fail();
280
    } catch (AssertionFailedError e) {
281
      assertTrue(e.getMessage().contains("toString representation"));
282
    }
283
  }
284

285
  private static void assertErrorMessage(Throwable e, String message) {
286
    // TODO(kevinb): use a Truth assertion here
287
    if (!e.getMessage().contains(message)) {
288
      fail("expected <" + e.getMessage() + "> to contain <" + message + ">");
289
    }
290
  }
291

292
  /**
293
   * Test class with valid equals and hashCode methods. Testers created with instances of this class
294
   * should always pass.
295
   */
296
  private static class ValidTestObject {
297
    private int aspect1;
298
    private int aspect2;
299

300
    ValidTestObject(int aspect1, int aspect2) {
301
      this.aspect1 = aspect1;
302
      this.aspect2 = aspect2;
303
    }
304

305
    @Override
306
    public boolean equals(@Nullable Object o) {
307
      if (!(o instanceof ValidTestObject)) {
308
        return false;
309
      }
310
      ValidTestObject other = (ValidTestObject) o;
311
      if (aspect1 != other.aspect1) {
312
        return false;
313
      }
314
      if (aspect2 != other.aspect2) {
315
        return false;
316
      }
317
      return true;
318
    }
319

320
    @Override
321
    public int hashCode() {
322
      int result = 17;
323
      result = 37 * result + aspect1;
324
      result = 37 * result + aspect2;
325
      return result;
326
    }
327
  }
328

329
  /** Test class with invalid hashCode method. */
330
  private static class InvalidHashCodeObject {
331
    private int aspect1;
332
    private int aspect2;
333

334
    InvalidHashCodeObject(int aspect1, int aspect2) {
335
      this.aspect1 = aspect1;
336
      this.aspect2 = aspect2;
337
    }
338

339
    @SuppressWarnings("EqualsHashCode")
340
    @Override
341
    public boolean equals(@Nullable Object o) {
342
      if (!(o instanceof InvalidHashCodeObject)) {
343
        return false;
344
      }
345
      InvalidHashCodeObject other = (InvalidHashCodeObject) o;
346
      if (aspect1 != other.aspect1) {
347
        return false;
348
      }
349
      if (aspect2 != other.aspect2) {
350
        return false;
351
      }
352
      return true;
353
    }
354
  }
355

356
  /** Test class that violates reflexivity. It is not equal to itself */
357
  private static class NonReflexiveObject {
358

359
    @Override
360
    public boolean equals(@Nullable Object o) {
361
      return false;
362
    }
363

364
    @Override
365
    public int hashCode() {
366
      return super.hashCode();
367
    }
368
  }
369

370
  /** Test class that returns true if the test object is null */
371
  private static class InvalidEqualsNullObject {
372

373
    @Override
374
    public boolean equals(@Nullable Object o) {
375
      return o == this || o == null;
376
    }
377

378
    @Override
379
    public int hashCode() {
380
      return 0;
381
    }
382
  }
383

384
  /** Test class that returns true even if the test object is of the wrong class */
385
  private static class InvalidEqualsIncompatibleClassObject {
386

387
    @Override
388
    public boolean equals(@Nullable Object o) {
389
      return o != null;
390
    }
391

392
    @Override
393
    public int hashCode() {
394
      return 0;
395
    }
396
  }
397

398
  private static NamedObject named(String name) {
399
    return new NamedObject(name);
400
  }
401

402
  private static class NamedObject {
403
    private final Set<String> peerNames = Sets.newHashSet();
404

405
    private final String name;
406

407
    NamedObject(String name) {
408
      this.name = Preconditions.checkNotNull(name);
409
    }
410

411
    NamedObject addPeers(String... names) {
412
      peerNames.addAll(ImmutableList.copyOf(names));
413
      return this;
414
    }
415

416
    @Override
417
    public boolean equals(@Nullable Object obj) {
418
      if (obj instanceof NamedObject) {
419
        NamedObject that = (NamedObject) obj;
420
        return name.equals(that.name) || peerNames.contains(that.name);
421
      }
422
      return false;
423
    }
424

425
    @Override
426
    public int hashCode() {
427
      return 0;
428
    }
429

430
    @Override
431
    public String toString() {
432
      return name;
433
    }
434
  }
435

436
  private static final class EqualsBasedOnToString {
437
    private final String s;
438

439
    private EqualsBasedOnToString(String s) {
440
      this.s = s;
441
    }
442

443
    @Override
444
    public boolean equals(@Nullable Object obj) {
445
      return obj != null && obj.toString().equals(toString());
446
    }
447

448
    @Override
449
    public int hashCode() {
450
      return s.hashCode();
451
    }
452

453
    @Override
454
    public String toString() {
455
      return s;
456
    }
457
  }
458
}
459

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.