Skip to content

StackOverflowError mocking our functional objects #890

Closed
@mziccard

Description

@mziccard

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.

Metadata

Metadata

Assignees

Labels

type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions