You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What steps will reproduce the problem?
1. Create abstract superclass AbstractSuperclass that does neither declare
equals() nor hashCode()
2. Create concrete subclass ConcreteSubclass that implements both equals() and
hashCode()
3. Run EqualsVerifier.forClass(ConcreteSubclass.class).verify()
What error message does EqualsVerifier give?
java.lang.AssertionError: Symmetry:
ConcreteSubclass [intValue=1, super=AbstractSuperclass [stringValue=one]]
does not equal superclass instance
AbstractSuperclass [stringValue=one]
What stacktrace does EqualsVerifier print, when called with the debug()
method?
java.lang.AssertionError: Symmetry:
ConcreteSubclass [intValue=1, super=AbstractSuperclass [stringValue=one]]
does not equal superclass instance
AbstractSuperclass [stringValue=one]
at nl.jqno.equalsverifier.util.Assert.assertTrue(Assert.java:85)
at nl.jqno.equalsverifier.HierarchyChecker.checkSuperclass(HierarchyChecker.java:92)
at nl.jqno.equalsverifier.HierarchyChecker.check(HierarchyChecker.java:61)
at nl.jqno.equalsverifier.EqualsVerifier.verifyWithExamples(EqualsVerifier.java:396)
at nl.jqno.equalsverifier.EqualsVerifier.performVerification(EqualsVerifier.java:366)
at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:333)
at equalsverifier.ContractTest.equalsContract(ContractTest.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
What did you expect?
Test should pass.
What version of EqualsVerifier are you using?
1.1.3
Please provide any additional information below.
Equalsverifier complains that concrete subclass does not equal *abstract*
superclass instance. However, an abstract class is not intended to be
instantiated.
As workaround, one can define both equals() and hashCode() as abstract in
AbstractSuperclass:
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
Then, the tests will pass as in line 78 of class HierarchyChecker there is a
check whether hashCode() is abstract in superclass.
Original issue reported on code.google.com by [email protected] on 8 May 2012 at 1:03
Hi,
Whether the superclass is abstract or not, should be irrelevant for the
symmetry check. If you haven't read it already, I recommend [1] for a starting
point for explanations of what kind of trouble inheritance can lead to w.r.t.
equality. Abstract superclasses are not immune to these issues, therefore
EqualsVerifier checks those as well.
That being said, if the superclass (whether it's abstract or concrete) has no
state and/or no equals/hashCode methods (or an abstract equals/hashCode
methods), then indeed it seems to make little sense to do this check. So that's
the real issue here, and I will fix this in the next release.
In the mean time, it should not be necessary to change your production code to
work around this issue. Fortunately you don't have to: add .usingGetClass() or
.withRedefinedSuperclass() to your call to EqualsVerifier, and your test should
also pass.
[1]
http://code.google.com/p/equalsverifier/wiki/FAQ#How_should_I_write_a_good_equal
s_method?
I've released a fix for this issue. EqualsVerifier will no longer check the
properties of the superclass if it doesn't redefine equals and hashCode. The
number of equals-less superclasses can be arbitrary.
Original issue reported on code.google.com by
[email protected]
on 8 May 2012 at 1:03Attachments:
The text was updated successfully, but these errors were encountered: