草庐IT

java - 是否不需要验证与 Mockito 中模拟的方法相同的方法?

coder 2024-03-29 原文

我经常看到验证的方法与 Mockito 中模拟的方法相同(如下例)。在这些情况下调用 Mockito.verify() 有什么额外的好处吗?

//mock method
FooService fs = mock(FooService.class);
when(fs.getFoo()).thenReturn("foo");

//method under test
fs.doSomething();

//verify method
verify(fs).getFoo();

如果未调用 fs.getFoo(),该方法将失败。那么为什么要调用verify呢?如果您需要在验证中使用 ArgumentCaptor 断言参数,我看到了好处;除了 ArgumentCaptor 案例之外,是否只是不必要的?

最佳答案

Mockito 文档反复说它通常是多余的。这在 verify(T)'s Javadoc 中逐字出现作为 Mockito's main class Javadoc section 2 中代码块中的多个单行注释:

Although it is possible to verify a stubbed invocation, usually it's just redundant. If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed). If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See here.

请注意,最初链接的文章“Asking and Telling”是由 Mockito 创始人 Szczepan Faber 撰写的,可以认为是 Mockito 设计中的权威文档。摘自该帖子:

Do I really have to repeat the same expression? After all, stubbed interactions are verified implicitly. The execution flow of my own code does it completely for free. Aaron Jensen also noticed that:

If you’re verifying you don’t need to stub unless of course that method returns something that is critical to the flow of your test (or code), in which case you don’t really need to verify, because the flow would have verified.

简单回顾一下:没有重复的代码

但是,如果一个有趣的交互具有询问和讲述的特征怎么办?我是否必须在 stub() 和 verify() 中重复交互?我最终会得到重复的代码吗?并不真地。在实践中:如果我 stub ,那么它是免费验证的,所以我不验证如果我验证,那么我不关心返回值,所以我不 stub 。无论哪种方式,I don’t repeat myself .不过从理论上讲,我可以想象一种罕见的情况,我确实验证了 stub 交互,例如确保 stub 交互恰好发生了 n 次。但这是行为的另一个方面,显然是一个有趣的方面。因此,我想说清楚一点,我非常乐意牺牲一行额外的代码……

最近版本的 Mockito(自发布此问答以来发布)添加了一些额外的功能 allowdefault to更严格的 mock 风格。尽管如此,普遍的期望是通过仅验证您无法通过断言或成功完成测试确认的内容来避免脆弱性。

总的来说,Mockito 的设计是让测试尽可能灵活,编码不是针对实现,而是针对您正在测试的方法的规范。尽管您偶尔会看到方法调用作为函数规范的一部分(“向服务器提交 RPC”或“立即调用传递的 LoginCallback”),但您更有可能希望验证可以执行的后置条件从 stub 中推断:检查 getFoo 是否被调用并不是规范的一部分,只要您 stub getFoo 返回“foo”并且数据存储包含一个其相应属性设置为“foo”的单个对象。


简而言之,仅显式验证无法从精心设计的 stub 和后置条件断言中隐含的交互被认为是良好的 Mockito 风格。它们可能是对其他方面无法衡量的副作用(记录代码、线程执行器、ArgumentCaptors、多方法调用、回调函数)的良好调用,但通常不应应用于 stub 交互。

关于java - 是否不需要验证与 Mockito 中模拟的方法相同的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35262529/

有关java - 是否不需要验证与 Mockito 中模拟的方法相同的方法?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  6. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  7. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  8. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  9. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  10. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

随机推荐