0

I've run into a little bit of trouble when trying to test interfacing with an external API. In particular a fair amount of classes that said API uses for data storage don't have equals and toString methods, which makes comparing whether the API created the objects I expect pretty difficult, as they are returned in a multitude of complex list-map combinations. Which if I wanted to manually check for equality I'd have to write a custom deep equality check every time.

So I was wondering if it is possible to inject a custom implementation of eqauls (and maybe even toString) into that class with PowerMock, Mockito and JUnit 4 (that's my test environment). Or if there is a way to tell JUnit to use a custom method to compare the objects of these data classes.
Libraries that integrate well with that setup are welcome.

BrainStone
  • 3,028
  • 6
  • 32
  • 59

2 Answers2

1

Those sort of methods are the same as if you would just write a proxy object for instance:

public class A {
    int c;
    int d;
}

public class B extends A {
    @Override
    public boolean equals(Object o) {
        if (o instanceof A) {
            A a = (A) o;
            return this.c == a.c && this.d == a.d;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return "B [c=" + c + ", d=" + d + "]";
    }
}

You can't reliably change the implementation of the underlying class (A) without risking exceptions propagating elsewhere in the code which may have relied on the behaviour of toString to equals, unlikely but this will still be a concern next time something stops working. If you are just going to do this in your testing and not in production however then this might be acceptable and you can consult existing questions in this area such as is it possible to override a method at runtime?

Derrops
  • 7,651
  • 5
  • 30
  • 60
  • I'm certain that it wouldn't mess up anything, as these methods are never called, because else they'd be implemented. (And I also checked the code and couldn't find any reference to those.) And I'm only going to do this in one or two test classes anyways, so it should be fine. But thanks for pointing this out! – BrainStone May 01 '18 at 01:37
  • All good just for general into on the `equals` method there might be 1 million references in your class path it will be impossible to figure out how things might behave differently, I would stick to the proxy method if you can. – Derrops May 01 '18 at 01:46
0

You're probably looking for some combination of Hamcrest matchers and assertThat e.g. assertThat(obj, matcher).

For example if you have a manually constructed instance you could use the SamePropertyValuesAs matcher to check the instances match.