Java 莫基托间谍怎么知道自己什么时候在进行间谍活动?

Java 莫基托间谍怎么知道自己什么时候在进行间谍活动?,java,unit-testing,mocking,mockito,spy,Java,Unit Testing,Mocking,Mockito,Spy,这完全让我困惑: 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"); List List=new

这完全让我困惑:

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");
List List=newlinkedlist();
列表间谍=间谍(列表);

当(spy.size())。然后返回(100);// 我不知道具体的实现方式,但我可以猜一猜

spy(…)
的调用首先代理给定对象,并将其作为委托调用的引用

电话

when(spy.size()).thenReturn(100);
实际上相当于

Integer result = spy.size();
OngoingStubbing<Integer> stubbing = when(result); // result is useless
stubbing.thenReturn(100);
Integer result=spy.size();
OngoingStubing stubing=当(结果);//结果是无用的
存根,然后返回(100);
在代理上调用对
size()
的第一个调用。在内部,它可以注册调用,例如在
静态
(全局)Mockito堆栈上推动调用。然后调用
When()
时,Mockito会从堆栈中弹出,将对
size()
的调用识别为需要存根,并执行执行执行此操作所需的任何逻辑


这可以解释为什么生意不好。

根据文档,第一个
何时(spy.size())。然后返回(100)
将实际调用real
List.size()
方法,请参阅:

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


如果您不希望调用真正的方法(例如,
when(spy.get(0)),那么return(…)
可能会抛出一个
IndexOutOfBoundsException
,您必须使用以下模式:
doReturn(…).when(spy.get(0)

以前已经回答过。请看@nadirsaghar我不知道你链接的答案是如何回答这个问题的。@DavidWallace你要让我看看源代码,是吗?嗯,我想亲自去看看源代码,只是为了提醒自己。但实际上你非常接近。没有全局堆栈,stubbing调用是在spy本身中注册的。但是所有其他细节都是正确的。我想我对你的否决票投得太匆忙了,现在我要删除我的否决票。嗯,我不得不做一个无关紧要的编辑来删除我的否决票。我有时讨厌这个网站。
spy
创建的东西不使用委托。它在一个添加了用于存根和验证的逻辑,但对于其所有方法,它对自身调用父方法,而不是对某些委托对象调用父方法。这是真的。我主张始终使用
doReturn(…)。当(…)
而不是担心何时需要
doReturn(…)。当(…)
以及何时可以使用
when(…)。然后返回(…)
。事实上,我已经在这个网站上发布了Mockito的答案,我建议在(…)时不要使用
。然后返回(…)
。@DavidWallace你的意思是说你建议在使用间谍时始终使用doReturn(),还是始终使用它,即使是在使用Mock?我倾向于在间谍时使用它,但发现经典的文(…)。然后…更具可读性,因此用于模拟。我的偏好是即使在模拟中也使用它。学习两个语法没有意义,因为只有一个语法可以涵盖所有情况。而且当
when/thenReturn
不起作用时,很难记住所有情况@JBNizet@JBNizet-看看我的答案。看起来我错了e当
不能用于间谍时,
。在我写这篇文章的时候,这可能是真的;我不确定。所以我会回去更正这个答案。无论如何,我的答案的基本信息仍然是真的。