Wiki
Clone wikideep-difference-utils / Home
About
The purpose of the deep-difference-utils library is to provide a convenient way of comparing objects in tests, including a deep recursive comparison of inner beans.
For example, let's assume you have a web application and different layers of entities: one layer is for DB, another layer is for a controller. With the help of this library, you can check in your tests that, for example, entity (from DB layer) is "deep equal" to corresponding DTO (from controller level), validating the correctness of the translation, between layers.
The configuration includes numerous ways of excluding properties from comparison, so only what you need will be compared.
Usage
Add it as maven dependency:
#!xml <dependency> <groupId>org.bitbucket.brunneng.deepdiff</groupId> <artifactId>deep-difference-utils</artifactId> <version>1.0.0</version> </dependency>
Let's assume we have the next model to work with:
#!java class Person { String name; int age; Address address; public Person(String name, int age, Address address) { this.name = name; this.age = age; this.address = address; } } class Address { String town; String street; public Address(String town, String street) { this.town = town; this.street = street; } } class PersonDTO { String name; int age; AddressDTO address; public PersonDTO(String name, int age, AddressDTO address) { this.name = name; this.age = age; this.address = address; } } class AddressDTO { String town; String street; public AddressDTO(String town, String street) { this.town = town; this.street = street; } }
The main class of this library is DeepDiffFinder, using it you can actually find differences:
#!java Person p = new Person("Harry", 25, null); PersonDTO dto = new PersonDTO("Harry", 24, null); System.out.println(new DeepDiffFinder().findDifferences(p, dto));
[Not equal values in path <"age">: <25> != <24>]
Method findDifferences returns the object of type Differences extends ArrayList<Difference> which provides methods to filter, search and exclude found differences.
Also, you may notice that the library works with fields, but if getters will be defined for them - then getters will be used to access the values.
Let's try another example:
#!java Person p = new Person("Harry", 25, new Address("London", "Great street")); PersonDTO dto = new PersonDTO("Harry", 25, new AddressDTO("Norwich", "Great street")); System.out.println(new DeepDiffFinder().findDifferences(p, dto));
[Not equal values in path <"address.town">: <London> != <Norwich>]
#!java Person p = new Person("Harry", 25, null, "Little secret"); PersonDTO dto = new PersonDTO("Harry", 25, null); System.out.println(new DeepDiffFinder().findDifferences(p, dto));
[Path <"secret"> exists only in 1st object]
If you want that such kind of differences shouldn't be detected and that it should compare only common fields, then it could be achieved like this:
#!java Person p = new Person("Harry", 25, null, "Little secret"); PersonDTO dto = new PersonDTO("Harry", 25, null); DeepDiffFinder finder = new DeepDiffFinder(new Configuration().compareOnlyCommonProperties()); System.out.println(finder.findDifferences(p, dto));
[]
By default, all beans are compared recursively. If you want to compare bean by equals it can be explicitly configured:
#!java Person p = new Person("Harry", 25, new Address("London", "Great street"), null); PersonDTO dto = new PersonDTO("Harry", 25, new AddressDTO("London", "Great street")); Configuration config = new Configuration(); config.compareOnlyCommonProperties(); config.beanOfClass(Address.class).applyCompareByEquals(); DeepDiffFinder finder = new DeepDiffFinder(config); System.out.println(finder.findDifferences(p, dto));
[Not equal values in path <"address">: <org.bitbucket.brunneng.deepdiff.UsageExample$Address@1bce4f0a> != <org.bitbucket.brunneng.deepdiff.UsageExample$AddressDTO@5e3a8624>]
The same effect could be achieved by configuring compare by equals on the property level:
#!java Person p = new Person("Harry", 25, new Address("London", "Great street"), null); PersonDTO dto = new PersonDTO("Harry", 25, new AddressDTO("London", "Great street")); Configuration config = new Configuration(); config.compareOnlyCommonProperties(); config.beanOfClass(Person.class).property("address").applyCompareByEquals(); DeepDiffFinder finder = new DeepDiffFinder(config); System.out.println(finder.findDifferences(p, dto));
Library detects the next types of differences:
EqualsDifference - Difference between two values which were compared by 'equals' and it returned 'false'.
OnlyOnePathExistsDifference - Difference which means that only one path to value exists, and therefore, values can't be actually compared. Appears when for example some property exists only in one object and doesn't exist in another.
CollectionDifference - Describes the difference between two collections.
MapDifference - Describes the difference between two maps.
Please see the Javadoc of the Configuration class and it's sub configurations Configuration.Bean and Configuration.Bean.Property to find more methods to configure the comparison process.
Updated