How to compare recursively ignoring given fields using assertJ?
Asked Answered
H

3

59

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?

Holst answered 10/4, 2017 at 6:16 Comment(0)
H
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.

Holst answered 13/4, 2017 at 7:27 Comment(1)
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 answer as it is better to use the Updated versions.Holst
D
127

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);
Disqualification answered 10/3, 2019 at 17:29 Comment(2)
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.Holst
this saved me from headache.Mohawk
H
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.

Holst answered 13/4, 2017 at 7:27 Comment(1)
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 answer as it is better to use the Updated versions.Holst
S
10

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.

Suburbia answered 19/8, 2022 at 20:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.