此示例代码:
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。
答案 0 :(得分:3)
因为在callstack中有org.mockito.internal.invocation.InvocationMatcher#matches
基本上是
invocation.getMock().equals(candidate.getMock())
(invocation.getMock()
是您的模拟Foo
实例)会导致对getBar
的调用被模拟,导致调用equals
- > getBar
- >模拟 - > equals
- > getBar
- >等...