扩展 - https://stackoverflow.com/a/29394497/1260692(因为stackoverflow不允许我在没有50声誉的情况下发表评论)
为什么在模拟设置期间以/然后样式调用间谍时会调用真正的方法?
我看到org.powermock.api.mockito.internal.expectation.DefaultMethodExpectationSetup(Mockito版本1.5.6)调用行号中的实际方法--44,46和52.一些Mockito专家可以解释为什么会发生这种情况,怎么避免这个?
仅供参考,当我切换到doReturn /样式时,没有问题。测试按预期运行。
答案 0 :(得分:0)
不知道PowerMock的来龙去脉,但调用when(foo.method())
...是使用通常的Java语义执行的:首先是方法调用foo.method()
,然后使用调用结果调用其他方法。现在,foo
是PowerMock创建的当时模拟对象。它不是空的,但有一大堆记录调用的逻辑。此模拟对象记录对method()
的调用。然后执行when()
方法调用并查询当前正在存根的模拟对象,该对象最后调用哪个方法以及哪些参数。此信息用于配置存根返回值。
Mockito的API看起来很神奇,但它只是一个非常巧妙设计的API,拥有大量完全正常的Java代码才能使其正常工作。 : - )
编辑:
换句话说:在when(foo.method())
中,foo是一个模拟对象,它有一个方法method()
,其代码与原始对象的代码无关,但处理对方法的记录调用。所以,既然这是普通的Java,那么首先执行foo.method()
。它根据原始方法签名的接口返回一些任意值(例如,method()
通常返回int时的int)。为了获取Mockito的信息,您要将foo.method()
存根,模拟对象与Mockito进行通信,老兄,我刚刚被称为"。带参数的方法还将调用它们的参数传递给Mockito。
因此,Mockito的when()
记住该调用并使用thenReturn()
方法返回一个对象。在调用它之前,将评估其参数。然后将该值传递给thenReturn()
方法,该方法与Mockio" dude进行通信,当被问及时,返回此"。 Mockito知道它正在对foo.method()
的调用进行存根,并将返回值内部连接到调用。所以稍后,当使用foo.method()
调用mock时,它会查找返回值并返回它。
我有点怀疑表达这种(doReturn().when()
)的另一种方式在根本上有所不同。