[英]Mockito produces StackOverflowError when mocked method is called in 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方法被稱為right。 我知道Mockito不存根equals
/ hashCode
/ toString
。 我也很清楚,HashSet調用equals
方法來查看其中是否已經有一個equal元素。 但是我不明白的是:為什么這個循環是無止境的?
使用的Mockito版本是2.8.9和JUnit 4.12。
因為在調用org.mockito.internal.invocation.InvocationMatcher#matches
有org.mockito.internal.invocation.InvocationMatcher#matches
,基本上是
invocation.getMock().equals(candidate.getMock())
( invocation.getMock()
是您的getBar
Foo
實例),這會導致對getBar
的調用, getBar
該getBar
被嘲笑會導致對equals
-> getBar
>模擬-> equals
-> getBar
>等等...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.