为什么Mock对象有doreturn和thenreturn formock?

Avi*_*thy 5 junit mockito powermock powermockito

注意:我知道在间谍中我们可以区分这两者。我查遍了互联网,但我仍然对 Mockito 中的 doreturn/when 和when/thenreturn 有一些疑问。以下是我的疑问,

1)doreturn/when 和when/thenreturn 对于模拟对象的行为是否相同?即:无论您为模拟对象调用 doreturn/when 还是 when/thenreturn 都没有关系,它不会调用真正的方法,而是调用存根调用。我对此的理解是否正确?

2)doreturn/when 和when/thenreturn 仅对 Mockito 中的间谍对象有影响。即 doreturn/when - 不会调用真正的方法,而when/thenreturn 将调用真正的方法。我对此的理解正确吗?

如果我对以上两点的理解是正确的,那么我们应该始终使用 doreturn/when 这样我们就不需要学习 2 种语法,对吗?

sis*_*hus 6

Mockito文档说明doReturn()

对于任何方法,您可以使用 doThrow()、doAnswer()、doNothing()、doReturn() 和 doCallRealMethod() 代替 when() 的相应调用。当你有必要

  • 存根无效方法
  • 间谍对象上的存根方法(见下文)
  • 多次存根同一方法,以在测试过程中更改模拟的行为。

并且...

在无法使用when(Object)的极少数情况下,请使用doReturn()。

给出了一个例子...

when(mock.foo()).thenThrow(new RuntimeException());

//不可能:调用异常存根的 foo() 方法,因此抛出 RuntimeException。when(mock.foo()).thenReturn("bar");

//你必须使用 doReturn() 进行存根:
doReturn("bar").when(mock).foo();

一般来说,您应该使用该when(...).thenReturn(...)语法,并且该语法有用的场合doReturn(...).when(...)很少。然而,值得注意的是,when(...)模拟 void 方法需要该模式,这种情况并不罕见。这只是doReturn(...)不太常用的语法。

具体回答您的问题:

  1. 不,这两种语法的工作方式略有不同 - 'doReturn(...)' 能够设置模拟对象以在调用模拟方法之前记录行为,而 'when(...)' 语法的工作原理是进行一些幕后操作来设置“thenReturn(...)”方法可以处理的存根处理程序。它们通常具有相同的效果,但在上面的极端情况中实现差异变得明显。

  2. 对于模拟,when(...)调用模拟对象上的存根方法。这就是为什么上面关于重新定义存根行为的极端情况很重要。


Avi*_*thy 4

经过我自己的实践,我才知道:

  1. doreturn/when 和when/thenreturn 对于模拟对象来说是相同的。他们都没有调用实际的方法
  2. doreturn/when 和when/thenreturn 对于监视对象有不同的行为。doreturn/when - 它不会调用监视对象上的真实方法 when/thenreturn - 它将调用监视对象上的真实方法

希望能帮助到你!