【问题标题】:Writing Specs for ActiveRecord association extensions为 ActiveRecord 关联扩展编写规范
【发布时间】:2011-09-28 07:09:06
【问题描述】:

例如,给定一个模型

class User < ActiveRecord::Base
  has_many :foos do
    def find_or_create_or_bar!(foo_name, foo_params)
      # ... stuff
      find_by_name(foo_name) || create!(foo_params) || bar!
    end
  end
end

谁能推荐一种编写行为规范的好方法?

describe User do
  describe "#foos" do
    describe "#find_or_create_or_bar!" do
      # ???
    end
  end
end

有没有一种很好的方法来考虑这些规格?我应该指定什么?由于这些是关联,甚至可以在这里单独指定User 类吗?

【问题讨论】:

  • 不确定这是否只是您尝试做的一个示例,但您的代码已经内置到 ActiveRecord 中:api.rubyonrails.org/classes/ActiveRecord/Base.html 读取基于动态属性的查找器
  • @Beerlington -- 是的,抱歉,我的例子不太有创意。我的意思是强调# ... stuff 部分,它不是ActiveRecord 的动态find_or_create 方法的一部分。

标签: ruby-on-rails ruby unit-testing activerecord rspec


【解决方案1】:

如果您担心用户规范对 Foo 模型了解太多,可以尝试将此逻辑移至 Foo 上的类方法:

这样的事情应该可以工作:

class Foo < ActiveRecord::Base

  def self.find_or_create_or_bar!(name, params)
    # ... stuff
    find_by_name(name) || create!(params) || bar!
  end

end

然后您可以在用户模型/规范之外进行测试。您可能还想进行集成测试,以确保 User 和 Foo 以您想要的方式进行交互。您可以为此使用 Rspec,但我发现 Cucumber 在涉及更多逻辑时更适合。

【讨论】:

  • 我经常使用 Cucumber,但我倾向于将它用于更高级别的东西——即在浏览器级别。您是否曾经使用 Cucumber 直接在您的模型上进行集成测试?
  • 另外,Foo.find_or_create_or_bar!(name, params)User 的关联有效吗? some_user.foos.find_or_create_or_bar!(...)
  • 我假设您使用的是 Rails 3,这可能不适用于 Rails 2:/
  • 我通常不使用 Cucumber 进行较低级别的模型测试,因为这就是 Test::Unit 或 Rspec 的设计目的。我的意思是你会想要一个使用这个类方法的更高级别的测试。这实际上只是 Rails 的内置行为,因此对关联方法调用进行单元测试有点多余。
  • 啊,是的,这就是我在大多数情况下尝试做的事情。我想促使我提出这个问题的原因是我刚刚编写了一种方法,其中# ... stuff 部分非常复杂。我想非常仔细地规范这种行为以确保正确的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多