Closed
Description
There seem to be a problem with EasyMock
(as well as Mockito
) when mocking classes that have a final
equals()
method that in its body calls other methods on the current object.
This results in a StackOverflowError as the following:
java.lang.StackOverflowError
at java.util.ArrayList$Itr.<init>(ArrayList.java:820)
at java.util.ArrayList$Itr.<init>(ArrayList.java:820)
at java.util.ArrayList.iterator(ArrayList.java:814)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:50)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:87)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:58)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:46)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:94)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97)
at com.google.gcloud.storage.Blob$$EnhancerByCGLIB$$aa59c155.toPb(<generated>)
at com.google.gcloud.storage.Blob.equals(Blob.java:529)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:85)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:57)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:87)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:58)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:46)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:40)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:94)
at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97)
at com.google.gcloud.storage.Blob$$EnhancerByCGLIB$$aa59c155.toPb(<generated>)
at com.google.gcloud.storage.Blob.equals(Blob.java:529)
To overcome this error all final
equals
methods should first check for "pointer" equality. For instance Blob.equals
must become:
@Override
public final boolean equals(Object obj) {
return this == obj || (obj instanceof Blob && Objects.equals(toPb(), ((Blob) obj).toPb())
&& Objects.equals(options, ((Blob) obj).options));
}
This should be fixed ASAP. Even tough we don't encourage users to mock our objects and provide test helpers to aid testing we don't want them to stumble upon this error.
This issue should remain open until fixed in compute as well.