My new favorite test tool: Unitils

I was working on some RESTful integration tests, and kept being annoyed at the repetetive nature in which I was verifying my user object. I knew I could override the equals() and hash() methods and simply call user.equal(newUser) to confirm whether users were equal, but I wanted a more universal solution that would not be limited to just my User objects. I knew someone had to have fixed this problem using reflection.

A few google searches later revealed the incredibly useful and powerful Unitils.org.

Old, ugly, repetitive assertions

...
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.Test;
import org.unitils.reflectionassert.ReflectionAssert;
import org.unitils.reflectionassert.ReflectionComparatorMode;
...

public class TestUserRestService {
...
    @Test
    public void test_createUser() throws Exception {
        String xml = this.getResponseAsString(response.getEntityInputStream());

        User uFromXml = (User) WSUtils.getObjectFromXml(xml); 

        Assert.assertNotNull(uFromXml); 
        Assert.assertEquals(u.getUserId(), uFromXml.getUserId()); 
        Assert.assertEquals(u.getPassword(), uFromXml.getPassword()); 
        Assert.assertEquals(u.getFirstName(), uFromXml.getFirstName()); 
        Assert.assertEquals(u.getLastName(), uFromXml.getLastName()); 
        Assert.assertEquals(u.getPhone(), uFromXml.getPhone()); 
        Assert.assertEquals(u.getZip(), uFromXml.getZip()); 
        Assert.assertEquals(u.getEmail(), uFromXml.getEmail()); 
        Assert.assertEquals(u.getAddress(), uFromXml.getAddress()); 
        Assert.assertEquals(u.getCity(), uFromXml.getCity()); 
        Assert.assertEquals(u.getState(), uFromXml.getState()); 
        Assert.assertEquals(u.getZip(), uFromXml.getZip()); 
    }
...
}

Simple, elegant one-line to verify code

        String xml = this.getResponseAsString(response.getEntityInputStream());

        User uFromXml = (User) WSUtils.getObjectFromXml(xml); 

        ReflectionAssert.assertReflectionEquals(u, uFromXml); 

That one line of code just replaced 12, and those 12 were not all attributes on the class, so that one line is much more useful than just replacing the initial 12 assertions mentioned above.

There were some issues with default values, but they have already thought of that and provide a parameter to ignore defaults.

        ReflectionAssert.assertReflectionEquals(u, uFromXml, ReflectionComparatorMode.IGNORE_DEFAULTS); 

I was kind of curious how it would handle certain Collection classes, and so far, for my simple Lists it appears to work as advertised.

    public static void main(String[] args) {
        List<String> g1 = new ArrayList<String>(); 
        g1.add("red"); 
        g1.add("blue"); 
        g1.add("yellow"); 

        List<String> g2 = new ArrayList<String>(); 
        g2.add("red"); 
        g2.add("blue"); 
        g2.add("green"); 

        User u1 = TestData.getTestUser_1("bob"); 
        u1.setUserGroups(g1);

        User u2 = TestData.getTestUser_1("bob");
        u2.setUserGroups(g2);

        ReflectionAssert.assertReflectionEquals(u1, u2); 
    }

This utility has significantly improved my test classes by making them much more thorough, and concise. I may even look to enhance (I want to pass a list of attributes to ignore). I just wish it was on GitHub instead of Sourceforge.