RSS

Category Archives: junit

Advanced Testing for Equality in Java Unit Tests

Testing the equals method
When testing Java classes, a common requirement is that the equals(Object) method works properly. When using JUnit, this can be as simple as:

import static org.junit.Assert.*;
:
assertEquals(a, b);

However, you may want to test that not only a considers itself equal to b but also vice versa. With a single assertEquals call this won’t work, so you add:

assertEquals(b, a);

Perfect, right?

Possibly. What if the test fails? How do you determine what the equals method actually considers a difference? The comparison algorithm can be quite complex, involving several instance fields, including collections, maps and XML snippets.

Differences for humans
It would help if the class would describe the differences in a human-readable manner. Here’s how: Declare an interface VerboseDiff (or whatever better name you can come up with) with just one method that describes the differences between this object and the specified argument. It returns null if there are no differences:

public interface VerboseDiff {
  String describeDifferences(Object obj);
}

Then change your implementation classes to implement this interface and implement the equals method as follows:

@Override
public boolean equals(Object obj) {
  return describeDifferences(obj) == null;
}

Your describeDifferences method could be implemented as follows:

public String describeDifferences(Object obj) {
  if (obj == null)) {
    return "obj == null";
  } else if (! (obj instanceof ThisClass)) {
    return "obj is not an instance of ThisClass, but an instance of class " + obj;
  }

  ThisClass that = (ThisClass) obj;

  if (that._baseValue != _baseValue) {
    return "baseValue of this object (" + _baseValue + ") is different from base value of argument (" + baseValue + ')';
  }

  return null;
}

Now your unit tests can look like this:

assertEquals(null, a.describeDifferences(b));
assertEquals(null, b.describeDifferences(a));

Further reading
A final tip: Implementing a good comparison algorithm that is in line with the contract of the equals method is typically not straight-forward, especially if you need to deal with subclasses. The article How to Write an Equality Method in Java (at artima.com) covers the topic excellently.

 
Leave a comment

Posted by on 1 July 2009 in diff, equals, java, junit, test, testing