Wednesday, July 1, 2009

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.

Tuesday, June 30, 2009

More CSS with Less

The people at Sitepoint send me a 'Tech Times' newsletter every now and then. I tend to ignore newsletters from most other companies, but this one is different, it is surprisingly interesting, most of the times.

Today's Tech Times (issue 246) informed me about Less, an improvement over regular CSS that adds variables, mixins, operations and nested rules to regular CSS. It's backwards compatible and compiles to regular CSS before you serve it to your favorite user agent. Wow.

This is definitely something I intend to integrate into the work flow for the PensioenPage technology, right before optimizing the (normal) CSS using the YUI Compressor.

Firefox 3.5 released

If you didn't know already, Firefox 3.5 was released today (June 30, 2009).

Of course, the PensioenPage technology is ready for it, even detecting the version properly, check out the source code:
www.pensioenpage.com/?_indent=true
Note that the _indent=true enables indentation in the source code.