java 形成 Mockito “语法”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11462697/
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
Forming Mockito "grammars"
提问by IAmYourFaja
Mockito seems like a pretty sweet stubbing/mocking framework for Java. The only problem is I can't find any concrete documentation on the best ways of using their API. Common methods used in tests include:
Mockito 似乎是一个非常棒的 Java stubbing/mocking 框架。唯一的问题是我找不到有关使用其 API 的最佳方法的任何具体文档。测试中常用的方法包括:
doXXX(???) : Stubber
when(T) : OngoingStubbing
then(T) : OngoingStubbing
verify(???) : T
given(T) : BDDOngoingStubbing
willXXX(???) : BDDStubber
When you see examples of Mockito in practice, you see code like:
当您在实践中看到 Mockito 示例时,您会看到如下代码:
when(yourMethod()).thenReturn(5);
From all the docs I've read, I've identified several "patterns" of Mockito "grammars" obtained from daisy-chaining these method calls together like the example above. Some common patterns I've found are:
从我读过的所有文档中,我已经确定了 Mockito“语法”的几个“模式”,这些“模式”是通过菊花链将这些方法调用连接在一起而获得的,就像上面的例子一样。我发现的一些常见模式是:
When/Then:when(yourMethod()).thenReturn(5);
Given/Will:given(yourMethod()).willThrow(OutOfMemoryException.class);
Do/When:doReturn(7).when(yourMock.fizzBuzz());
Will/Given/Do:willReturn(any()).given(yourMethod()).doNothing();
Verify/Do:verify(yourMethod()).doThrow(SomeException.class);
何时/那么:when(yourMethod()).thenReturn(5);
给定/遗嘱:给定(yourMethod())。willThrow(OutOfMemoryException.class);
做/何时:doReturn(7).when(yourMock.fizzBuzz());
Will/Given/Do:willReturn(any()).given(yourMethod()).doNothing();
验证/执行:verify(yourMethod()).doThrow(SomeException.class);
What I'm choking on is how to select the right pattern/combination of method calls to model my test cases. It seems like you can daisy-chain these together in seemingly endless combos and I'm not sure what pattern is right for which problem.
我正在纠结的是如何选择正确的方法调用模式/组合来为我的测试用例建模。似乎您可以将这些以看似无穷无尽的组合菊花链式连接在一起,但我不确定哪种模式适合哪个问题。
Can some Mockito Guru help shed some light as to which patterns/combinations of Mockito methods are used for which types of test cases (and why)? Thanks in advance!
某些 Mockito Guru 能否帮助阐明 Mockito 方法的哪些模式/组合用于哪些类型的测试用例(以及为什么)?提前致谢!
采纳答案by Matt
Mockito often have several ways of doing things.
Mockito 通常有多种做事方式。
I find myself using mostly:
我发现自己主要使用:
// Setup expectations
when(object.method()).thenReturn(value);
when(object.method()).thenThrow(exception);
doThrow(exception).when(object.voidMethod());
// verify things
verify(object, times(2)).method();
verify(object, times(1)).voidMethod();
I've found that i can do 95% of what i need to with these three kinds of calls.
我发现我可以用这三种调用完成我需要做的 95% 的事情。
Also, what version of Mockito are you using? "given" and "will" constructs are not present in the latest version (1.9.0+)
另外,您使用的是什么版本的 Mockito?最新版本 (1.9.0+) 中不存在“given”和“will”结构
However, there are cases where I want the return value or exception to respond to the input. In this case, you can use the Answer interface to inspect the method arguments and return an appropriate value.
但是,在某些情况下,我希望返回值或异常响应输入。在这种情况下,您可以使用 Answer 接口来检查方法参数并返回适当的值。
public class ReturnFirstArg<T> implements Answer<T> {
public T answer(InvocationOnMock invocation) {
return invocation.getArguments()[0];
}
}
when(object.method(7)).thenAnswer(new ReturnFirstArg<Integer>());
回答by Dawood ibn Kareem
There are several disadvantages to the when/thenReturn
, when/thenThrow
and when/then
syntaxes. For example,
when/thenReturn
,when/thenThrow
和when/then
语法有几个缺点。例如,
- In the case of
when/thenReturn
, if the return type is a generic with a wildcard, and you wish to return a mock of the same type, you will be unable to avoid a compile warning. - You can't use
when/thenThrow
andwhen/then
for a void method. - You can't use these syntaxes on Mockito spies.
- You can only call
when
once for each combination of mock object, method and arguments, unless you callreset
on the mock. - Calling
when
multiple times for one combination of mock object and method, when you are using argument matchers, can lead to problems.
- 在 的情况下
when/thenReturn
,如果返回类型是带有通配符的泛型,并且您希望返回相同类型的模拟,则将无法避免编译警告。 - 您不能将
when/thenThrow
andwhen/then
用于 void 方法。 - 你不能在 Mockito 间谍上使用这些语法。
when
对于模拟对象、方法和参数的每个组合,您只能调用一次,除非您调用reset
模拟。when
当您使用参数匹配器时,为模拟对象和方法的一种组合多次调用可能会导致问题。
I find these cases difficult to remember. So instead of trying to keep track of when the
when/thenReturn
, when/thenThrow
and when/then
syntaxes will and won't work, I prefer to avoid them completely, in favour of the doReturn/when
, doThrow/when
and doAnswer/when
alternatives. That is to say, since you'll occasionally need doReturn/when
, doThrow/when
and doAnswer/when
, and you can ALWAYS use these methods, there is no point in learning how to use when/thenReturn
, when/thenThrow
and when/then
.
我发现这些案例很难记住。因此,与其试图跟踪
when/thenReturn
, when/thenThrow
andwhen/then
语法何时起作用和不起作用,我宁愿完全避免它们,而支持doReturn/when
,doThrow/when
和doAnswer/when
替代方案。也就是说,由于您偶尔会需要doReturn/when
,doThrow/when
和doAnswer/when
,并且您可以始终使用这些方法,因此学习如何使用when/thenReturn
,when/thenThrow
和是没有意义的when/then
。
Note that doReturn
, doThrow
and doAnswer
can be chained together in the same way as thenReturn
, thenThrow
and then
. What they don't have is an option for returning several values (or throwing several exceptions, or running several answers) within a single call to doReturn
, doThrow
and doAnswer
. But I find that I need to do this so seldom, that it doesn't really matter.
需要注意的是doReturn
,doThrow
并doAnswer
可以以同样的方式链接在一起thenReturn
,thenThrow
和then
。他们没有的是在对doReturn
,doThrow
和的单个调用中返回多个值(或抛出多个异常,或运行多个答案)的选项doAnswer
。但我发现我很少需要这样做,这并不重要。
There's one more disadvantage to doReturn
, which I consider insignificant. You don't get compile time checking of the type of its argument, like you do with when/thenReturn
. So if you get the argument type wrong, you won't find out until you run your test. Frankly, I don't care.
还有一个缺点doReturn
,我认为这无关紧要。您不会像使用when/thenReturn
. 因此,如果您弄错了参数类型,则在运行测试之前您不会发现。坦白说,我不在乎。
In summary then, I have been using Mockito for more than two years, and I consider the consistent use of doReturn
, doThrow
and doAnswer
to be a Mockito best practice. Other Mockito users disagree.
总之呢,我已经使用了的Mockito两年多了,我考虑是一致的使用doReturn
,doThrow
并且doAnswer
是一个最好的Mockito实践。其他 Mockito 用户不同意。
回答by Adrian Shum
The things in fact looks much simpler than you thought
事情实际上看起来比你想象的要简单得多
REF: http://static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html
参考:http: //static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html
Verify:
验证:
In order to use Mockito, you need to understand one basic philosophy of Mockito: Stubbing and Verification is separated. Therefore, the "Verify/Do" you mentioned is in fact doing the "Verification" job, while the other 4 "grammars" is for stubbing. Stubbing define how the mock object will react in different situation. Verification is to make sure what the mocks is invoked as expected, in previous invocation to system under test (SUT).
为了使用 Mockito,您需要了解 Mockito 的一个基本理念:Stubbing 和 Verification 是分开的。因此,你提到的“Verify/Do”实际上是在做“Verification”的工作,而其他4个“grammars”是用于stubbing的。存根定义了模拟对象在不同情况下的反应。验证是为了确保在先前对被测系统 (SUT) 的调用中按预期调用了哪些模拟。
When/Then , Given/Will:
何时/那么,给定/将:
Then it come to the "When" and "Given" families. You can simply treat them as aliases of each other. "Given" family is added in Mockito 1.8.x as to make it looks more aligned to BDD practices.
然后是“When”和“Given”系列。您可以简单地将它们视为彼此的别名。Mockito 1.8.x 中添加了“Given”系列,使其看起来更符合 BDD 实践。
DoXxx:
DoXxx:
In normal case we mostly use when(xxx).then(...)
(and given(...).will(...)
) . However there are some case that syntax is not working. The most obvious case is when return type of the stubbed method is void. In such case when(mockObj.voidMethod()).thenThrow(anException)
is not going to compile. As a workaround, an alternative syntax of Do/When is created, so you can write the previous line as doThrow(anException).when(mockObj.voidMethod())
在正常情况下,我们主要使用when(xxx).then(...)
(and given(...).will(...)
) 。但是,在某些情况下,语法不起作用。最明显的情况是当存根方法的返回类型为 void 时。在这种情况下when(mockObj.voidMethod()).thenThrow(anException)
是不会编译的。作为解决方法,创建了 Do/When 的替代语法,因此您可以将上一行写为doThrow(anException).when(mockObj.voidMethod())