I had the similar situation when I couldn't implement equals/hashCode
in the legacy code.
Let me share a solution based on the wrapper pattern. You wrap your legacy class and implement equals/hashCode
there. In your tests you create a sets of wrapped objects and test it by regular way.
public class SomethingTest {
class SomethingWrapper {
private final Something value;
SomethingWrapper(Something value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SomethingWrapper that = (SomethingWrapper) o;
return new EqualsBuilder()
.append(value.a, that.value.a)
.append(value.b, that.value.b)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(value.a)
.append(value.b)
.toHashCode();
}
}
@Test
public void compareSomethingSetsWithoutEquals() {
final Set<Something> originalA = new HashSet<>();
originalA.add(new Something("a1", "b1"));
originalA.add(new Something("a2", "b2"));
final Set<Something> originalB = new HashSet<>();
originalB.add(new Something("a1", "b1"));
originalB.add(new Something("a2", "b2"));
final Set<SomethingWrapper> aWrappedSetA =
originalA.stream().map(SomethingWrapper::new).collect(Collectors.toSet());
final Set<SomethingWrapper> aWrappedSetB =
originalB.stream().map(SomethingWrapper::new).collect(Collectors.toSet());
assertEquals(aWrappedSetA, aWrappedSetB);
}
}