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