Better reflection equals
ctapobep opened this issue · comments
Current samePropertyValuesAs()
has many downsides and doesn't seem to be usable in real projects:
- It uses properties instead of fields
- It can't work with ORM proxies
- It's a shallow comparison
Unitils' assertReflectionEquals() seems to solve this problem well in general (but it's not supported and it has its own issues), I wonder if Hamcrest can also solve this problem. Approx. syntax could be:
assertThat(actual,
ReflectionMatcher.withDepth(1)
.matchEndNodesUsingEqualsThenField("id")
.unproxyIfNeeded(new HibernateUnproxer())
.excludingFields("blah")
.modes(COLLECTION_LINIENT_ORDER)
.equalsTo(expected)
);
where:
depth(0)
means infinite recursionunproxyIfNeeded()
will return real object instead of Hibernate (or whatever) proxy. This can't work in Hamcrest Core as it will depend on ORM. So by default it will through an exception. Multiple one-class dependencies can be implemented for different ORMs.matchEndNodesUsingEqualsThenField("id")
is needed to compare fields at deepest level if depth != 0. The objects are compared withequals()
by default, but those classes may not have equals() in which case we need to compare some representative field(s). This method may accept a map ofClass -> fieldNames[]
if different classes have different ID fields.excludingFields()
should also be overloaded to acceptClass -> fieldNames[]
modes()
is similar to Unitils' modes
Even if no one is going to implement it right now I wonder if such matcher would be accepted if I were to implement it some day?
Since this seems like a big project, no one will probably take it. So I'll try to create the matcher as a separate project: https://github.com/qala-io/assert-reflection-equals