Mockito – doReturn()和when()之间的区别
我目前正在使用Mockito在我想testing我的Controller方法的Spring MVC应用程序中模拟我的服务层对象。 然而,正如我一直在阅读Mockito的具体细节,我发现方法doReturn(...).when(...)
等于when(...).thenReturn(...)
。 所以,我的问题是有两个方法做同样的事情或什么是doReturn(...).when(...)
之间的细微差别是什么doReturn(...).when(...)
和when(...).thenReturn(...)
?
任何帮助,将不胜感激。
两种用于存根的语法大致相同。 但是,您可以随时使用doReturn/when
for doReturn/when
; 但有些情况下,你不能使用when/thenReturn
。 虚空方法就是这样的一个例子。 其他的包括与Mockito间谍一起使用,并且不止一次地用相同的方法存根。
有一件事, when/thenReturn
给你,那么doReturn/when
时候不,是在编译时检查你返回的值的types检查。 不过,我相信这几乎是没有价值的 – 如果你的types错了,你会发现一旦你运行你的testing。
我强烈build议只使用doReturn/when
。 学习两种语法是没有意义的。
你可能希望参考我的答案在形成Mockito“语法” – 一个非常密切相关的问题更详细的答案。
如果您使用spied对象(使用@Spy
注释)而不是模拟(使用@Mock
注释),则两种方法的行为@Spy
:
-
when(...) thenReturn(...)
在返回指定值之前进行实际的方法调用 。 所以如果被调用的方法抛出一个exception,你必须处理它/模拟它等等。当然,你仍然得到你的结果(你在thenReturn(...)
定义的) -
doReturn(...) when(...)
根本不调用该方法 。
例:
public class MyClass { protected String methodToBeTested() { return anotherMethodInClass(); } protected String anotherMethodInClass() { throw new NullPointerException(); } }
testing:
@Spy private MyClass myClass; // ... // would work fine doReturn("test").when(myClass).anotherMethodInClass(); // would throw a NullPointerException when(myClass.anotherMethodInClass()).thenReturn("test");
后面的替代方法用于返回void
。
请看看,例如,在这里: 如何使模拟无效方法与mockito
继续这个答案 ,还有一个区别是,如果你想你的方法返回不同的值,例如当第一次调用,第二次调用等,那么你可以传递值,所以例如…
PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));
所以当方法在同一个testing用例中被调用时,它将返回false,然后它将再次返回false,并且最后是true。
Mockito javadoc似乎告诉了为什么使用doReturn()
而不是when()在不能使用Mockito.when(Object)的情况下,在那些罕见的情况下使用doReturn()。
注意Mockito.when(Object)总是被推荐用于存根,因为它是参数types安全的并且更具可读性(特别是当连续调用存根时)。
以下是doReturn()派上用场的罕见场合:
当间谍侦察真实的对象和调用真正的方法带来副作用
List list = new LinkedList(); List spy = spy(list);
//不可能:真正的方法被调用所以spy.get(0)抛出IndexOutOfBoundsException(该列表尚未空)
when(spy.get(0)).thenReturn("foo");
//你必须使用doReturn()来存根:
doReturn("foo").when(spy).get(0);
2.覆盖以前的例外情况:
when(mock.foo()).thenThrow(new RuntimeException());
//不可能:调用exception存根foo()方法,引发RuntimeException。
when(mock.foo()).thenReturn("bar");
//您必须使用doReturn()进行存根:
doReturn("bar").when(mock).foo();
以上场景展示了Mockito优雅语法的折衷。 请注意,情景是非常罕见的,虽然。 间谍应该是零星的,压倒一切的例外情况非常罕见。 更不用说,一般来说,被覆盖的残片是一种潜在的代码味道,指出了太多的残片。
“模拟”可以模拟一个对象,而不是创build它;“间谍”可以创build一个具有实际参数的实际对象。 当我们做unit testing时,我们经常使用它们。 但是,当(xxx).thenReturn(xxx)'用于模拟,'doReturn(xxx).when(xxx)'用于间谍。