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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |