【问题标题】:RSpec: check if any model has been savedRSpec:检查是否已保存任何模型
【发布时间】:2013-02-08 09:49:48
【问题描述】:

在我的 Rails 应用程序中,我创建了一个基于 JSON 数据创建模型层次结构的方法。我想确保该方法不会将任何内容保存到数据库中。我知道我可以编写如下测试:

expect {
  Importer.import(json)
}.not_to change(Model1, :count)
expect {
  Importer.import(json)
}.not_to change(Model2, :count)
# etc.

但我想以更通用的方式来做。 RSpec 中是否有一种方法可以检查在测试期间是否保存了任何模型?

【问题讨论】:

    标签: ruby-on-rails database rspec mocking


    【解决方案1】:

    你做这件事的方式还不错,虽然有点冗长。 您可以使用have 匹配器。

    Importer.import(json)
    collection1 = Model.all
    collection1.should have(5).items
    
    ...
    
    collection2.should_not have(5).items
    
    # etc....
    

    但是,就您的上下文而言,像原始测试一样阅读它更有意义(除了创建一个真正有意义的自定义匹配器之外)。您测试“进口商”应该做什么或不做什么。

    have(n).items matcher

    【讨论】:

      【解决方案2】:

      如果“import”方法可以返回一个Model对象,你可以这样写期望:

      imported_obj = Importer.import(json)
      expect(imported_obj).not_to be_persisted
      

      be_persisted”是一个predicate-matcher,它只是在imported_obj 上调用persisted? 方法。该方法“持续存在?”是 Rails 的方法,如果imported_obj 已保存,则返回true。

      【讨论】:

        【解决方案3】:

        不确定 Rspec 是否可以帮助您,但是快速手动访问数据库可能会完成这项工作?

        [Model1, Model2].each do |model|
          model.where('updated_at > ?', Time.now - 2.seconds).count.should eq 0
        end
        

        【讨论】:

        • 查看更新时间的风险很大。如果测试运行缓慢(例如由于 CI 服务器上的问题),可能会得到奇怪的结果。不过,感谢您的回答;-)。
        • 对于未来的读者:这种类型的测试特别容易出错。你永远不应该在测试中依赖硬编码的时间间隔——这是一个失败的测试,不管它有时是否通过。
        猜你喜欢
        • 2015-03-08
        • 2021-08-29
        • 1970-01-01
        • 2012-07-09
        • 2021-06-25
        • 2016-11-30
        • 1970-01-01
        • 2011-01-13
        • 2014-10-27
        相关资源
        最近更新 更多