Tuesday, May 21, 2013

easier testing with unitils

Many times in my unit tests I needed to assert that two objects equals while they didn't implement equals method or the equals method wasn't appropriate to ensure that these object are logically the same. So the obvious solution was to write several asserts comparing particular fields from given objects:

import static org.testng.Assert.assertEquals;
...
@Test
public void test() {
Project actualProject = ...
Project expectedProject = ...
assertEquals(actualProject.getName(), expectedProject.getDeadline())
assertEquals(actualProject.getDeadline(), expectedProject.getLastName())
assertEquals(actualProject.getManager().getFirstName(), expectedProject.getManager().getFirstName());
assertEquals(actualProject.getManager().getLastName(), expectedProject.getManager().getLastName());
}

Today I came across Unitils, a great library that facilitates writing tests in Java. It consists of several modules, but the most interesting for me is Reflection Assert. It provides an assertReflectionEquals method that verifies if two objects are equal - field by field, recursively.

import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
...
@Test
public void test() {
Project actualProject = ...
Project expectedProject = ...
assertReflectionEquals(expectedProject, actualProject);
}

That's it! Isn't it easy?

Additionally it gives a detailed info when assertion fails. Here is samle output:

Expected: Project<name="Project A", deadline=Mon May 05 10:00:00 CEST 2014, manager=Manager<firstName="John", lastName="Orange">>
Actual: Project<name="Project A", deadline=Sun May 05 10:00:00 CEST 2013, manager=Manager<firstName="John", lastName="Lemon">>
--- Found following differences ---
manager.lastName: expected: "Orange", actual: "Lemon"
deadline: expected: Mon May 05 10:00:00 CEST 2014, actual: Sun May 05 10:00:00 CEST 2013
--- Difference detail tree ---
expected: Project<name="Project A", deadline=Mon May 05 10:00:00 CEST 2014, manager=Manager<firstName="John", lastName="Orange">>
actual: Project<name="Project A", deadline=Sun May 05 10:00:00 CEST 2013, manager=Manager<firstName="John", lastName="Lemon">>
manager expected: Manager<firstName="John", lastName="Orange">
manager actual: Manager<firstName="John", lastName="Lemon">
manager.lastName expected: "Orange"
manager.lastName actual: "Lemon"
deadline expected: Mon May 05 10:00:00 CEST 2014
deadline actual: Sun May 05 10:00:00 CEST 2013