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可能不是這方面最好的用例。 –