alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (EqualsTesterTest.java)

This example Java source code file (EqualsTesterTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

assertionfailederror, equalstester, invalidequalsincompatibleclassobject, invalidequalsnullobject, invalidhashcodeobject, namedobject, nonreflexiveobject, nullpointerexception, object, override, should, string, testcase, util, validtestobject

The EqualsTesterTest.java Java example source code

/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.testing;

import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;

import junit.framework.AssertionFailedError;
import junit.framework.TestCase;

import java.util.Set;

/**
 * Unit tests for {@link EqualsTester}.
 *
 * @author Jim McMaster
 */
@GwtCompatible
public class EqualsTesterTest extends TestCase {
  private ValidTestObject reference;
  private EqualsTester equalsTester;
  private ValidTestObject equalObject1;
  private ValidTestObject equalObject2;
  private ValidTestObject notEqualObject1;

  @Override
  public void setUp() throws Exception {
    super.setUp();
    reference = new ValidTestObject(1, 2);
    equalsTester = new EqualsTester();
    equalObject1 = new ValidTestObject(1, 2);
    equalObject2 = new ValidTestObject(1, 2);
    notEqualObject1 = new ValidTestObject(0, 2);
  }

  /**
   * Test null reference yields error
   */
  public void testAddNullReference() {
    try {
      equalsTester.addEqualityGroup((Object) null);
      fail("Should fail on null reference");
    } catch (NullPointerException e) {}
  }

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

  /**
   * Test adding null equal object yields error
   */
  public void testAddNullEqualObject() {
    try {
      equalsTester.addEqualityGroup(reference, (Object[]) null);
      fail("Should fail on null equal object");
    } catch (NullPointerException e) {}
  }

  /**
   * Test adding objects only by addEqualityGroup, with no reference object
   * specified in the constructor.
   */
  public void testAddEqualObjectWithOArgConstructor() {
    equalsTester.addEqualityGroup(equalObject1, notEqualObject1);
    try {
      equalsTester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
        e,
        equalObject1 + " [group 1, item 1] must be Object#equals to "
            + notEqualObject1 + " [group 1, item 2]");
      return;
    }
    fail("Should get not equal to equal object error");
  }

  /**
   * Test EqualsTester with no equals or not equals objects.  This checks
   * proper handling of null, incompatible class and reflexive tests
   */
  public void testTestEqualsEmptyLists() {
    equalsTester.addEqualityGroup(reference);
    equalsTester.testEquals();
  }

  /**
   * Test EqualsTester after populating equalObjects.  This checks proper
   * handling of equality and verifies hashCode for valid objects
   */
  public void testTestEqualsEqualsObjects() {
    equalsTester.addEqualityGroup(reference, equalObject1, equalObject2);
    equalsTester.testEquals();
  }

  /**
   * Test proper handling of case where an object is not equal to itself
   */
  public void testNonreflexiveEquals() {
    Object obj = new NonReflexiveObject();
    equalsTester.addEqualityGroup(obj);
    try {
      equalsTester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e, obj + " must be Object#equals to itself");
      return;
    }
    fail("Should get non-reflexive error");
  }

  /**
   * Test proper handling where an object tests equal to null
   */
  public void testInvalidEqualsNull() {
    Object obj = new InvalidEqualsNullObject();
    equalsTester.addEqualityGroup(obj);
    try {
      equalsTester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e, obj + " must not be Object#equals to null");
      return;
    }
    fail("Should get equal to null error");
  }

  /**
   * Test proper handling where an object incorrectly tests for an
   * incompatible class
   */
  public void testInvalidEqualsIncompatibleClass() {
    Object obj = new InvalidEqualsIncompatibleClassObject();
    equalsTester.addEqualityGroup(obj);
    try {
      equalsTester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e,
          obj
          + " must not be Object#equals to an arbitrary object of another class");
      return;
    }
    fail("Should get equal to incompatible class error");
  }

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

  /**
   * Test for an invalid hashCode method, i.e., one that returns different
   * value for objects that are equal according to the equals method
   */
  public void testInvalidHashCode() {
    Object a = new InvalidHashCodeObject(1, 2);
    Object b = new InvalidHashCodeObject(1, 2);
    equalsTester.addEqualityGroup(a, b);
    try {
      equalsTester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e, "the Object#hashCode (" + a.hashCode() + ") of " + a
          + " [group 1, item 1] must be equal to the Object#hashCode ("
          + b.hashCode() + ") of " + b);
      return;
    }
    fail("Should get invalid hashCode error");
  }

  public void testNullEqualityGroup() {
    EqualsTester tester = new EqualsTester();
    try {
      tester.addEqualityGroup((Object[]) null);
      fail();
    } catch (NullPointerException e) {}
  }

  public void testNullObjectInEqualityGroup() {
    EqualsTester tester = new EqualsTester();
    try {
      tester.addEqualityGroup(1, null, 3);
      fail();
    } catch (NullPointerException e) {
      assertErrorMessage(e, "at index 1");
    }
  }

  public void testSymmetryBroken() {
    EqualsTester tester = new EqualsTester()
        .addEqualityGroup(named("foo").addPeers("bar"), named("bar"));
    try {
      tester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e,
          "bar [group 1, item 2] must be Object#equals to foo [group 1, item 1]");
      return;
    }
    fail("should failed because symmetry is broken");
  }

  public void testTransitivityBrokenInEqualityGroup() {
    EqualsTester tester = new EqualsTester()
        .addEqualityGroup(
            named("foo").addPeers("bar", "baz"),
            named("bar").addPeers("foo"),
            named("baz").addPeers("foo"));
    try {
      tester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e,
          "bar [group 1, item 2] must be Object#equals to baz [group 1, item 3]");
      return;
    }
    fail("should failed because transitivity is broken");
  }

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

  public void testTransitivityBrokenAcrossEqualityGroups() {
    EqualsTester tester = new EqualsTester()
        .addEqualityGroup(
            named("foo").addPeers("bar"),
            named("bar").addPeers("foo", "x"))
        .addEqualityGroup(
            named("baz").addPeers("x"),
            named("x").addPeers("baz", "bar"));
    try {
      tester.testEquals();
    } catch (AssertionFailedError e) {
      assertErrorMessage(
          e,
          "bar [group 1, item 2] must not be Object#equals to x [group 2, item 2]");
      return;
    }
    fail("should failed because transitivity is broken");
  }

  public void testEqualityGroups() {
    new EqualsTester()
        .addEqualityGroup(
            named("foo").addPeers("bar"), named("bar").addPeers("foo"))
        .addEqualityGroup(named("baz"), named("baz"))
        .testEquals();
  }

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

  /**
   * Test class with valid equals and hashCode methods.  Testers created
   * with instances of this class should always pass.
   */
  private static class ValidTestObject {
    private int aspect1;
    private int aspect2;

    ValidTestObject(int aspect1, int aspect2) {
      this.aspect1 = aspect1;
      this.aspect2 = aspect2;
    }

    @Override public boolean equals(Object o) {
      if (!(o instanceof ValidTestObject)) {
        return false;
      }
      ValidTestObject other = (ValidTestObject) o;
      if (aspect1 != other.aspect1) {
        return false;
      }
      if (aspect2 != other.aspect2) {
        return false;
      }
      return true;
    }

    @Override public int hashCode() {
      int result = 17;
      result = 37 * result + aspect1;
      result = 37 * result + aspect2;
      return result;
    }
  }

  /** Test class with invalid hashCode method. */
  private static class InvalidHashCodeObject {
    private int aspect1;
    private int aspect2;

    InvalidHashCodeObject(int aspect1, int aspect2) {
      this.aspect1 = aspect1;
      this.aspect2 = aspect2;
    }

    @Override public boolean equals(Object o) {
      if (!(o instanceof InvalidHashCodeObject)) {
        return false;
      }
      InvalidHashCodeObject other = (InvalidHashCodeObject) o;
      if (aspect1 != other.aspect1) {
        return false;
      }
      if (aspect2 != other.aspect2) {
        return false;
      }
      return true;
    }
  }

  /** Test class that violates reflexitivity.  It is not equal to itself */
  private static class NonReflexiveObject {

    @Override public boolean equals(Object o) {
      return false;
    }

    @Override public int hashCode() {
      return super.hashCode();
    }
  }

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

    @Override public boolean equals(Object o) {
      return o == this || o == null;
    }

    @Override public int hashCode() {
      return 0;
    }
  }

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

    @Override public boolean equals(Object o) {
      return o != null;
    }

    @Override public int hashCode() {
      return 0;
    }
  }

  private static NamedObject named(String name) {
    return new NamedObject(name);
  }

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

    private final String name;

    NamedObject(String name) {
      this.name = Preconditions.checkNotNull(name);
    }

    NamedObject addPeers(String... names) {
      peerNames.addAll(ImmutableList.copyOf(names));
      return this;
    }

    @Override public boolean equals(Object obj) {
      if (obj instanceof NamedObject) {
        NamedObject that = (NamedObject) obj;
        return name.equals(that.name) || peerNames.contains(that.name);
      }
      return false;
    }

    @Override public int hashCode() {
      return 0;
    }

    @Override public String toString() {
      return name;
    }
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java EqualsTesterTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.