2

文档中的这段代码让我完全困惑:

List list = new LinkedList();
List spy = spy(list);

when(spy.size()).thenReturn(100); // <--- how does this spy know 
// not to call the real method????

//using the spy calls *real* methods
spy.add("one");
spy.add("two");

我明白了,Mockito 很奇怪,而且几乎不在 Java 中。令人困惑的事情是spy.*在它知道它是否被包裹在一个when()或什么东西之前必须完全评估。第spy.*一种方法到底怎么会不调用真实对象,但后来的方法呢?

4

2 回答 2

2

根据文档,第一个when(spy.size()).thenReturn(100)实际上会调用真正的List.size()方法,请参阅: http: //mockito.github.io/mockito/docs/current/org/mockito/Mockito.html#13

当然,随后的每个调用都会返回模拟结果。

如果您不希望调用真正的方法(例如when(spy.get(0)).thenReturn(...)可能会抛出一个IndexOutOfBoundsException,您必须使用此模式:doReturn(...).when(spy).get(0);

于 2014-11-13T23:42:13.740 回答
1

我不知道确切的实现,但我可以猜测一下。

对 first 的调用spy(...)代理给定对象并将其作为对委托调用的引用。

通话

when(spy.size()).thenReturn(100);

实际上相当于

Integer result = spy.size();
OngoingStubbing<Integer> stubbing = when(result); // result is useless
stubbing.thenReturn(100);

size()在代理上调用第一个调用。在内部,它可以注册调用,将其推static送到(全局)Mockito 堆栈上。然后,当您调用when()时,Mockito 从堆栈中弹出,将调用识别size()为需要存根并执行所需的任何逻辑。

这可以解释为什么在多线程环境中存根是不好的业务。

于 2014-11-13T23:19:52.453 回答