在同一个对象上多次调用Mockito。 [英] Calling Mockito.when multiple times on same object?

查看:1547
本文介绍了在同一个对象上多次调用Mockito。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当试图在Spring中使用Mockito时,通过bean声明创建Mock对象...

 < bean id =accountMapperclass =org.mockito.Mockitofactory-method =mock> 
< constructor-arg value =org.example.persistence.mybatis.mappers.AccountMapper/>
< / bean>

...我在多次调用Mockito时发现了一些奇怪的行为而没有重置Mock对象,例如:

  Mockito.when(this.accountMapper.createBadGrammarException())。thenThrow(new BadSqlGrammarException(Bla,null ,new SQLException())); 

在测试期间多次调用此代码(Mockito.when)时(在同一个模拟器上,测试失败并出现错误(BadSqlGrammerException,即使这个异常是实际预期的 - 如果我不抛出异常,我会失败,并且手动抛出它可以正常工作)。这是预期的行为吗? Mockito 似乎建议每次创建一个新模拟器,这意味着为每种方法创建DAO ......?



当我两次调用Mockito.when方法时会发生什么?模拟应该如何反应?替换行为?忽略它?不幸的是,大多数搜索只会产生如何为方法本身的多次调用返回不同结果的结果,但不会产生多次调用Mockito的预期结果。



<我只是想在这里理解Mockito和最佳实践,因为只是因为SEEMS才能实现,这似乎是一个坏主意......

解决方案

Mockito.when 的一个问题是你传递给它的参数是你试图存根的表达式。因此,当您使用 Mockito.when 两次进行相同的方法调用时,第二次使用它时,您实际上将获得第一次存根的行为。



我实际上建议不要使用 Mockito.when 。使用它时可能会遇到许多陷阱 - 很多情况下,当您需要其他语法时。 更安全的替代语法是Mockito方法的do系列。

  doReturn(value).when(mock)。方法(参数......); 
doThrow(exception).when(mock).method(arguments ...);
doAnswer(回答).when(mock).method(arguments ...);

所以在你的情况下,你想要

  doThrow(new BadSqlGrammarException(??,??,??))。when(accountMapper).createBadGrammarException(); 

如果你开始使用Mockito,那么我建议你学习使用do系列。它们是模拟void方法的唯一方法,而Mockito文档特别提到了这一点。但是只要 Mockito.when 可以使用它们就可以使用它们。因此,如果您使用do系列,您的测试结果会更加一致,而且学习曲线会更少。



有关案例的更多信息当必须使用do系列时,请参阅形成Mockito语法的答案


When trying to use Mockito with Spring, by creating the Mock object via a bean declaration...

<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:

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? Mockito seems to suggest creating a new mock every time, which would mean creating the DAO for each method...?

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...

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...

解决方案

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.

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.

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.

For more information about the cases when you must use the "do" family, see my answer on Forming Mockito "grammars"

这篇关于在同一个对象上多次调用Mockito。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆