51

AssertJ has isEqualToIgnoringGivenFields and isEqualToComparingFieldByFieldRecursively.

But, there is no way I can compare two objects recursively by ignoring some fields. As per this discussion, it must be in development.

How to still get my assert's return value to be compared recursively but ignoring some fields. Is it possible in any other library or can I do it somehow using AssertJ?

Tarun Maganti
  • 3,076
  • 2
  • 35
  • 64

3 Answers3

116

With latest 'Recursive comparison api improvements' from AssertJ release 3.12.0 it's possible now to do a recursive comparison and ignore fields:

Assertions.assertThat(objActual)
                .usingRecursiveComparison()
                .ignoringFields("uniqueId", "otherId")
                .ignoringFieldsMatchingRegexes(".*someId")
                .ignoringOverriddenEqualsForTypes(MyData.class, MyDataItem.class)
                .isEqualTo(objExpected);
Ovidiu Nistor
  • 1,163
  • 2
  • 7
  • 7
  • 3
    I marked my answer as accepted because when I had the problem with a particular version, I solved it using that way. But, I'd recommend any new comers to check this particular answer as it is better to use the Updated versions. – Tarun Maganti Jan 16 '20 at 09:16
  • this saved me from headache. – RamPrakash Mar 25 '22 at 02:15
11

I couldn't get it to ignore some fields but I managed to temporarily solve it by introducing a comparator for the fields which I want to ignore and always evaluated them to true. This is not fluent but a temporary solution to get the job done.

assertThat(object).usingComparatorForFields((x,y)->0,"field1","field2").isEqualToComparingFieldByFieldRecursively(expectedObject);

This has an issue as of April 13, 2017. It doesn't work when the fields which the comparator is trying to compare are null. This is an issue when one of objects is null not if both are null.

Tarun Maganti
  • 3,076
  • 2
  • 35
  • 64
  • I marked my answer as accepted because when I had the problem with a particular version, I solved it using that way. But, I'd recommend any new comers to check [Ovidiu Nistor's](https://stackoverflow.com/users/4602948/ovidiu-nistor) [answer](https://stackoverflow.com/a/55090416/4669984) as it is better to use the Updated versions. – Tarun Maganti Jan 16 '20 at 09:18
7

Dunno if that was your exact question, but what used to trip me up a lot was that for the ignoring fields function is that "navigation" to the fields to ignore is not considering array / Iterable boundaries.

That is, if I have a class book that has many pages (e.g. if you have a one-to-many relationship and save it to your relational database), I can ignore the fact that "book.pages" is an array, and just work with "book.pages.id" like there was only one page all the time, like so:

assertThat(actualBook)
    .usingRecursiveComparison()
    .ignoringFields("id", "pages.id", "pages.book")
    .isEqualTo(expectedBook);

Why is this confusing? Because if you forget to ignore fields, the exception will state that there is a mismatch in, say, "pages[2].id" - but you won't need that index "[2]" in the ignore statement.

RobertG
  • 1,550
  • 1
  • 23
  • 42