Java 在同一个对象上多次调用 Mockito.when ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31512245/
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
Calling Mockito.when multiple times on same object?
提问by Florian Schaetz
When trying to use Mockito with Spring, by creating the Mock object via a bean declaration...
当尝试在 Spring 中使用 Mockito 时,通过 bean 声明创建 Mock 对象......
<bean id="accountMapper" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.example.persistence.mybatis.mappers.AccountMapper" />
</bean>
...I found some strange behavior when calling Mockito.when multiple times without reseting the Mock object, for example:
...在不重置 Mock 对象的情况下多次调用 Mockito.when 时,我发现了一些奇怪的行为,例如:
Mockito.when(this.accountMapper.createBadGrammarException()).thenThrow(new BadSqlGrammarException("Bla", null, new SQLException()));
As soon as this code (the "Mockito.when") is called multiple time during the test (on the same mock), the tests fails with an error (BadSqlGrammerException even if this exception was what was actually expected - I do get a failure if I don't throw the exception, and throwing it manually works fine). Is this expected behavior? Mockitoseems to suggest creating a new mock every time, which would mean creating the DAO for each method...?
一旦在测试期间多次调用此代码(“Mockito.when”)(在同一个模拟上),测试就会失败并出现错误(BadSqlGrammerException 即使此异常是实际预期的 - 我确实遇到了失败如果我不抛出异常,并且手动抛出它可以正常工作)。这是预期的行为吗?Mockito似乎建议每次都创建一个新的模拟,这意味着为每种方法创建 DAO ......?
What exactly happens when I call the Mockito.when method two times? How should the mock react? Replace the behavior? Ignore it? Unfortunately most searches only yield results for how to return different results for multiple calls to the method itself, but not what is to be expected for multiple calls to Mockito.when...
当我两次调用 Mockito.when 方法时到底发生了什么?模拟应该如何反应?替换行为?忽略它?不幸的是,大多数搜索只产生关于如何为多次调用方法本身返回不同结果的结果,而不是对多次调用 Mockito.when 的预期结果...
I'm simply trying to understand Mockito and best practices here, because going with something just because it SEEMS to works seems to be a bad idea...
我只是想了解 Mockito 和这里的最佳实践,因为仅仅因为它看起来有效而使用某些东西似乎是一个坏主意......
采纳答案by Dawood ibn Kareem
One of the problems with Mockito.when
is that the argument you pass to it is the expression that you're trying to stub. So when you use Mockito.when
twice for the same method call, the second time you use it, you'll actually get the behaviour that you stubbed the first time.
问题之一Mockito.when
是您传递给它的参数是您试图存根的表达式。因此,当您Mockito.when
对同一个方法调用使用两次时,第二次使用它时,您实际上会获得第一次存根的行为。
I actually recommend NOT using Mockito.when
. There are many traps that you can fall into when you use it - quite a few cases when you need some other syntax instead. The "safer" alternative syntax is the "do" family of Mockito methods.
我实际上建议不要使用Mockito.when
. 当您使用它时,您可能会陷入许多陷阱 - 当您需要一些其他语法时,会遇到很多情况。“更安全”的替代语法是 Mockito 方法的“do”系列。
doReturn(value).when(mock).method(arguments ...);
doThrow(exception).when(mock).method(arguments ...);
doAnswer(answer).when(mock).method(arguments ...);
So in your case, you want
所以在你的情况下,你想要
doThrow(new BadSqlGrammarException(??, ??, ??)).when(accountMapper).createBadGrammarException();
If you are starting out with Mockito, then I recommend that you learn to use the "do" family. They're the only way to mock void methods, and the Mockito documentation specifically mentions that. But they can be used whenever Mockito.when
can be used. So if you use the "do" family, you'll end up with more consistency in your tests, and less of a learning curve.
如果您刚开始使用 Mockito,那么我建议您学习使用“do”系列。它们是模拟 void 方法的唯一方法,Mockito 文档特别提到了这一点。但是只要可以使用它们就可以使用它们Mockito.when
。因此,如果您使用“do”系列,您最终会在测试中获得更高的一致性,并且学习曲线会更短。
For more information about the cases when you mustuse the "do" family, see my answer on Forming Mockito "grammars"
有关必须使用“do”系列的情况的更多信息,请参阅我对形成 Mockito“语法”的回答
回答by Vova Yatsyk
The simple answer is:
when you write Mockito.when(object.fooMethod()).then()
then fooMethod()
is actually called.
Another point is that we can't observe it first time, because it called on mocked object. But when we write when
for the second time then we have some behavior for fooMethod()
(we set it previously, in your case it Exception).
简单的答案是:
当你写Mockito.when(object.fooMethod()).then()
thenfooMethod()
实际上被调用。
还有一点是我们不能第一次观察它,因为它调用了模拟对象。但是当我们when
第二次写入时,我们有一些行为fooMethod()
(我们之前设置了它,在你的情况下它是异常)。
To check this better you can spy
object:
为了更好地检查这一点,您可以spy
反对:
Bar spyBar = Mockito.spy(Bar.class)
when(spyBar.fooMethod()).then()...
and fooMethod()
will be actually called.
并且fooMethod()
会被实际调用。