0
此示例代码:的Mockito产生的StackOverflowError当模拟的方法被调用的equals()/ hashCode()方法
public final class FooBarTest {
@Test
public void test() {
final Foo foo = mock(Foo.class);
when(foo.getBar()).thenReturn(1);
new HashSet().add(foo);
}
private class Foo {
@Override
public final boolean equals(final Object other) {
return getBar() == 0;
}
public int getBar() {
return 0;
}
@Override
public final int hashCode() {
return getBar();
}
}
}
产生无限循环并抛出异常:
java.lang.StackOverflowError
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:57)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:43)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptSuperCallable(MockMethodInterceptor.java:119)
at de.weltraumschaf.maconha.FooBarTest$Foo$MockitoMock$217383798.getBar(Unknown Source)
at de.weltraumschaf.maconha.FooBarTest$Foo.equals(FooBarTest.java:24)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:81)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:82)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:90)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:32)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:57)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:43)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptSuperCallable(MockMethodInterceptor.java:119)
at de.weltraumschaf.maconha.FooBarTest$Foo$MockitoMock$217383798.getBar(Unknown Source)
at de.weltraumschaf.maconha.FooBarTest$Foo.equals(FooBarTest.java:24)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:81)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:82)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:90)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:32)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:57)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:43)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptSuperCallable(MockMethodInterceptor.java:119)
at de.weltraumschaf.maconha.FooBarTest$Foo$MockitoMock$217383798.getBar(Unknown Source)
at de.weltraumschaf.maconha.FooBarTest$Foo.equals(FooBarTest.java:24)
...
我调试进代码,并在Mockito的深度迷失。我能看到的唯一情况是equals方法被称为正确的。我知道Mockito不存根equals
/hashCode
/toString
。我也很清楚,HashSet调用equals
方法来查看它是否已经有相同的元素。但是我无法弄清楚:为什么这个循环是无止境的?
使用的Mockito版本是2.8.9和JUnit 4.12。
可能是由于Mockito使用equals方法本身来验证它是同一个对象。如果您为了减少问题而不重写hash和equals会发生什么? Mockito可能不是这方面最好的用例。 –