RSS

Advanced Testing for Equality in Java Unit Tests

01 Jul

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.

Advertisements
 
Leave a comment

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

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: