com.emarsys.ecommon.test.testng
Class EqualsHashCodeTest<T>

java.lang.Object
  extended by com.emarsys.ecommon.test.testng.EqualsHashCodeTest<T>

public abstract class EqualsHashCodeTest<T>
extends java.lang.Object

EqualsHashCodeTest is a template (aka base class) for TestNG unit tests that check the validity of overridden Object.equals(Object) and Object.hashCode() methods.

Extend this class in order to test a class's functional compliance with the Object.equals(Object) and Object.hashCode() contract.

Override newEqualInstance() and newNotEqualInstance() methods to provide objects to test against. Both methods should return objects that are of the same class T.

NOTE: This class is only usefull if the class under testing overrides #equalTs(Object) in order to test for equivalence. If #equalTs(Object) tests for identity, i.e. it preserves the behavior from Object, setUp() will throw an IllegalArgumentException because newEqualInstance() is supposed to return equivalent but distinct objects.

EqualsHashCodeTest's design is inspired by the equally named class in junit-addons. It's not just a port to TestNG but a complete reimplementation of the class that reuses only some concepts of the junit-addons implementation, so there should be no licensing issues.

See items 7-8 in http://trac.emarsys.com/e3/wiki/EffectiveJava for more details on Object.equals(Object) and its contract.

TODO's

  • I'm not very happy with the current design of the class which forces implementors to subclass it - maybe it's possible to elegantly decouple this test mechanism by using TestNG's

    Author:
    Michael "kULO" Kulovits

    See Also:
    Object.equals(Object),


    Field Summary
    protected  java.util.List<java.lang.Object> equalObjs
              A List of equal but not equivalent objects of type T, declared as the super type Object.
    protected  java.util.List<T> equalTs
              A List of equal but not equivalent objects of type T.
    protected static int NBR_OF_ITEMS
               
    protected static int NBR_OF_ITERATIONS
               
    protected  java.util.List<java.lang.Object> nEqualObjs
              A List of pairwise distinct objects of type T, declared as the super type Object.
    protected  java.util.List<T> nEqualTs
              A List of pairwise distinct objects of type T.
     
    Constructor Summary
    EqualsHashCodeTest()
               
     
    Method Summary
    protected
    <E> void
    checkPrecond(java.util.List<E> equals, java.util.List<E> nEquals)
              Asserts the preconditions for the passed List of equal and non-equal elements.
    protected  java.util.List<java.lang.Object> getAll()
               
    protected  java.util.List<java.lang.Object> getAllEquals()
               
    protected  java.util.List<java.lang.Object> getAllNotEquals()
               
    protected  int getNbrOfItems()
              In order to change the number of items being checked override this method in your subclass.
    protected  int getNbrOfIterations()
              In order to change the number of items being checked override this method in your subclass.
    protected abstract  T newEqualInstance()
              creates a new instance of the class under test.
    protected abstract  T newNotEqualInstance()
              creates a new instance of the class under test.
     void setUp()
              setup the objects needed for the test comparisons and check all preconditions.
     void tearDown()
               
     void testEqualsAgainstNewObject()
              tests whether T#equals(Object) holds up against a new Object (should always be false).
     void testEqualsAgainstNull()
              tests whether T#equals(Object) holds up against null.
     void testEqualsAgainstUnequalObjects()
              tests whether T#equals(Object) holds up against objects that should not compare equal.
     void testEqualsIsConsistentAcrossInvocations()
              tests whether T#equals(Object) is consistent accross at least #this.getNbrOfIterations() invocations.
     void testEqualsIsReflexive()
              tests whether Object.equals(Object) is reflexive.
     void testEqualsIsSymmetricAndTransitive()
              tests whether T#equals(Object) is symmetric and transitive.
    protected
    <E> void
    testEqualsNot(java.util.List<E> eqs, java.util.List<E> neqs)
               
     void testHashCodeContract()
              tests the hashCode contract.
     void testHashCodeIsConsistentAcrossInvocations()
              tests the consistency of hashCode accross serveral invacations.
    protected
    <E> void
    testReflexive(java.util.List<E> es)
               
    protected
    <E> void
    testSymmetryTransitivity(java.util.List<E> es)
               
     
    Methods inherited from class java.lang.Object
    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
     

    Field Detail

    NBR_OF_ITEMS

    protected static final int NBR_OF_ITEMS
    See Also:
    Constant Field Values

    NBR_OF_ITERATIONS

    protected static final int NBR_OF_ITERATIONS
    See Also:
    Constant Field Values

    equalTs

    protected java.util.List<T> equalTs
    A List of equal but not equivalent objects of type T.


    equalObjs

    protected java.util.List<java.lang.Object> equalObjs
    A List of equal but not equivalent objects of type T, declared as the super type Object. The declaration as Object is needed because of Object.equals(Object) being a binary method and the possible issues with subclasses that violate the substitution principle.


    nEqualTs

    protected java.util.List<T> nEqualTs
    A List of pairwise distinct objects of type T. Every element of this list must be distinct from the equal elements in equalTs.


    nEqualObjs

    protected java.util.List<java.lang.Object> nEqualObjs
    A List of pairwise distinct objects of type T, declared as the super type Object. Every element of this list must be distinct from the equal elements in equalObjs. The declaration as Object is needed because of Object.equals(Object) being a binary method and the possible issues with subclasses that violate the substitution principle.

    Constructor Detail

    EqualsHashCodeTest

    public EqualsHashCodeTest()
    Method Detail

    newEqualInstance

    protected abstract T newEqualInstance()
                                   throws java.lang.Exception
    creates a new instance of the class under test. will be called at least 2 * getNbrOfItems() times on every test method.

    Returns:
    a new instance of the class under test; each object returned from this method should compare equal to each other but not equivalent.
    Throws:
    java.lang.Exception

    newNotEqualInstance

    protected abstract T newNotEqualInstance()
                                      throws java.lang.Exception
    creates a new instance of the class under test. will be called at least 2 * getNbrOfItems() times on every test method. subsequent calls might provide only slightly distinct instances according to the number of distinct properties in order to do a more/most fine grained check.

    Returns:
    a new instance of the class under test; each object returned from this method must not compare equal to each other and to the objects returned from newEqualInstance().
    Throws:
    java.lang.Exception

    getNbrOfItems

    protected int getNbrOfItems()
    In order to change the number of items being checked override this method in your subclass.

    Returns:
    the number of (equal or pairwise unequal) items this check should test; must be >= 3 in order to check #equalTs(Object) and Object.hashCode() for transitivity.

    getNbrOfIterations

    protected int getNbrOfIterations()
    In order to change the number of items being checked override this method in your subclass.

    Returns:
    the number of (equal or pairwise unequal) items this check should test; must be >= 3 in order to check #equalTs(Object) and Object.hashCode() for transitivity.

    setUp

    public void setUp()
               throws java.lang.Exception
    setup the objects needed for the test comparisons and check all preconditions.

    Throws:
    java.lang.Exception

    checkPrecond

    protected <E> void checkPrecond(java.util.List<E> equals,
                                    java.util.List<E> nEquals)
    Asserts the preconditions for the passed List of equal and non-equal elements.

    Type Parameters:
    E -
    Parameters:
    equals -
    nEquals -

    tearDown

    public void tearDown()
                  throws java.lang.Exception
    Throws:
    java.lang.Exception

    getAllEquals

    protected java.util.List<java.lang.Object> getAllEquals()
    Returns:

    getAllNotEquals

    protected java.util.List<java.lang.Object> getAllNotEquals()
    Returns:

    getAll

    protected java.util.List<java.lang.Object> getAll()
    Returns:

    testEqualsAgainstNewObject

    public final void testEqualsAgainstNewObject()
    tests whether T#equals(Object) holds up against a new Object (should always be false).


    testEqualsAgainstNull

    public final void testEqualsAgainstNull()
    tests whether T#equals(Object) holds up against null.


    testEqualsAgainstUnequalObjects

    public final void testEqualsAgainstUnequalObjects()
    tests whether T#equals(Object) holds up against objects that should not compare equal.


    testEqualsNot

    protected final <E> void testEqualsNot(java.util.List<E> eqs,
                                           java.util.List<E> neqs)
    Type Parameters:
    E -
    Parameters:
    eqs -
    neqs -

    testEqualsIsReflexive

    public final void testEqualsIsReflexive()
    tests whether Object.equals(Object) is reflexive.


    testReflexive

    protected final <E> void testReflexive(java.util.List<E> es)
    Type Parameters:
    E -
    Parameters:
    es -

    testEqualsIsSymmetricAndTransitive

    public final void testEqualsIsSymmetricAndTransitive()
    tests whether T#equals(Object) is symmetric and transitive.


    testSymmetryTransitivity

    protected final <E> void testSymmetryTransitivity(java.util.List<E> es)
    Type Parameters:
    E -
    Parameters:
    es -

    testEqualsIsConsistentAcrossInvocations

    public final void testEqualsIsConsistentAcrossInvocations()
    tests whether T#equals(Object) is consistent accross at least #this.getNbrOfIterations() invocations.


    testHashCodeContract

    public final void testHashCodeContract()
    tests the hashCode contract.


    testHashCodeIsConsistentAcrossInvocations

    public final void testHashCodeIsConsistentAcrossInvocations()
    tests the consistency of hashCode accross serveral invacations.



    Copyright © 2010 emarsys AG. All Rights Reserved.