Java Mockito - doReturn() 和 when() 之间的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20353846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mockito - difference between doReturn() and when()
提问by blackpanther
I am currently in the process of using Mockito to mock my service layer objects in a Spring MVC application in which I want to test my Controller methods. However, as I have been reading on the specifics of Mockito, I have found that the methods doReturn(...).when(...)
is equivalent to when(...).thenReturn(...)
. So, my question is what is the point of having two methods that do the same thing or what is the subtle difference between doReturn(...).when(...)
and when(...).thenReturn(...)
?
我目前正在使用 Mockito 在 Spring MVC 应用程序中模拟我的服务层对象,我想在其中测试我的控制器方法。但是,由于我一直在阅读 Mockito 的细节,我发现这些方法doReturn(...).when(...)
等效于when(...).thenReturn(...)
. 所以,我的问题是让两种方法做同样的事情有什么意义,或者doReturn(...).when(...)
和之间的细微差别是when(...).thenReturn(...)
什么?
Any help would be appreciated.
任何帮助,将不胜感激。
采纳答案by Dawood ibn Kareem
The two syntaxes for stubbing are roughly equivalent. However, you can alwaysuse doReturn/when
for stubbing; but there are cases where you can'tuse when/thenReturn
. Stubbing void methods is one such. Others include use with Mockito spies, and stubbing the same method more than once.
存根的两种语法大致相同。但是,您始终可以将其doReturn/when
用于存根;但在某些情况下您不能使用when/thenReturn
. 存根 void 方法就是这样一种方法。其他包括与 Mockito 间谍一起使用,并多次使用相同的方法。
One thing that when/thenReturn
gives you, that doReturn/when
doesn't, is type-checking of the value that you're returning, at compile time. However, I believe this is of almost no value - if you've got the type wrong, you'll find out as soon as you run your test.
when/thenReturn
给你的一件事是doReturn/when
在编译时对你返回的值进行类型检查。但是,我相信这几乎没有任何价值 - 如果您的类型错误,您会在运行测试后立即发现。
I strongly recommend only using doReturn/when
. There is no point in learning two syntaxes when one will do.
我强烈建议只使用doReturn/when
. 当一种语法可以学习时,学习两种语法是没有意义的。
You may wish to refer to my answer at Forming Mockito "grammars"- a more detailed answer to a very closely related question.
您可能希望参考我在Forming Mockito “grammars” 中的回答 - 对一个非常密切相关的问题的更详细的回答。
回答by vikingsteve
The latter alternative is used for methods on mocks that return void
.
后一种替代方法用于返回void
.
Please have a look, for example, here: How to make mock to void methods with mockito
请看一下,例如,这里: How to make mock to void methods with mockito
回答by akcasoy
Both approaches behave differently if you use a spied object (annotated with @Spy
) instead of a mock (annotated with @Mock
):
如果您使用被监视的对象(用 注释@Spy
)而不是模拟(用 注释@Mock
),两种方法的行为会有所不同:
when(...) thenReturn(...)
makes a real method calljust before the specified value will be returned. So if the called method throws an Exception you have to deal with it / mock it etc. Of course you still get your result (what you define inthenReturn(...)
)doReturn(...) when(...)
does not call the method at all.
when(...) thenReturn(...)
在返回指定值之前进行真正的方法调用。所以如果被调用的方法抛出一个异常,你必须处理它/模拟它等等。当然你仍然得到你的结果(你在 中定义的thenReturn(...)
)doReturn(...) when(...)
根本不调用该方法。
Example:
例子:
public class MyClass {
protected String methodToBeTested() {
return anotherMethodInClass();
}
protected String anotherMethodInClass() {
throw new NullPointerException();
}
}
Test:
测试:
@Spy
private MyClass myClass;
// ...
// would work fine
doReturn("test").when(myClass).anotherMethodInClass();
// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");
回答by AZ_
Continuing this answer, There is another difference that if you want your method to return different values for example when it is first time called, second time called etc then you can pass values so for example...
继续这个答案,还有另一个区别,如果您希望您的方法返回不同的值,例如第一次调用,第二次调用等时,那么您可以传递值,例如...
PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));
So it will return false when the method is called in same test case and then it will return false again and lastly true.
因此,当在同一测试用例中调用该方法时,它将返回 false,然后再次返回 false,最后返回 true。
回答by AZ_
The Mockito javadoc seems to tell why use doReturn()
instead of when()
Use doReturn() in those rare occasions when you cannot use Mockito.when(Object).
Mockito javadoc 似乎说明了为什么
在无法使用 Mockito.when(Object) 的极少数情况下使用doReturn()
而when()
不是使用 doReturn()。
Beware that Mockito.when(Object) is always recommended for stubbing because it is argument type-safe and more readable (especially when stubbing consecutive calls).
Here are those rare occasions when doReturn() comes handy:
1.When spying real objects and calling real methods on a spy brings side effects
List list = new LinkedList(); List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing:
doReturn("foo").when(spy).get(0);
2.Overriding a previous exception-stubbing:
when(mock.foo()).thenThrow(new RuntimeException());
//Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown.
when(mock.foo()).thenReturn("bar");
//You have to use doReturn() for stubbing:
doReturn("bar").when(mock).foo();
Above scenarios shows a tradeoff of Mockito's elegant syntax. Note that the scenarios are very rare, though. Spying should be sporadic and overriding exception-stubbing is very rare. Not to mention that in general overridding stubbing is a potential code smell that points out too much stubbing.
请注意,始终建议将 Mockito.when(Object) 用于存根,因为它是参数类型安全的且更具可读性(尤其是在存根连续调用时)。
以下是 doReturn() 派上用场的罕见情况:
1.当spy真正的对象,在spy上调用真正的方法会带来副作用
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());
//不可能:调用异常存根的 foo() 方法因此抛出 RuntimeException。
when(mock.foo()).thenReturn("bar");
//您必须使用 doReturn() 进行存根:
doReturn("bar").when(mock).foo();
以上场景显示了 Mockito 优雅语法的权衡。但请注意,这种情况非常罕见。监视应该是零星的,并且覆盖异常存根是非常罕见的。更不用说一般来说,覆盖存根是一种潜在的代码异味,指出存根过多。