【问题标题】:Factory Girl error with has_many relationship工厂女孩错误与 has_many 关系
【发布时间】:2010-10-28 22:58:01
【问题描述】:

我有以下工厂:

Factory.define :email do |email|
  email.email {"infomcburney.cowan.com"}
end

Factory.define :lead do |lead|
  lead.emails {|emails| [emails.association(:email)]}
end

哪些是建模以下类

class Lead < ActiveRecord::Base
  has_many :emails
end

class Email < ActiveRecord::Base
  belongs_to :lead, :class_name => "Lead", :foreign_key => "lead_id"
end

当我通过 shoulda 运行这个测试时:

    should "capture emails" do
      lead = Factory.build(:lead)
      assert_equal(1, lead.emails.size)
    end

我收到以下错误:

Factory::AttributeDefinitionError: 属性已定义:电子邮件

我完全坚持这一点,谁能指出我正确的方向。我正在使用 factory_girl 1.3.2。

【问题讨论】:

  • 风格要点:工厂应包含占位符数据,仅此而已。使用它们时对您来说重要的是生成了有效的潜在客户,并且您应该假设附加到潜在客户的电子邮件的实际数量可能会发生变化。如果您的测试依赖于一定数量的潜在客户,请从工厂构建潜在客户,然后明确设置电子邮件。

标签: ruby-on-rails factory-bot


【解决方案1】:

我建议不要将 has_many 关系数据添加到您的工厂。原因是您的主导工厂现在依赖于填充此关联,并且如果关联发生变化,它会增加更多的耦合并可能会造成一些混乱。

如果您想测试这种关系(我建议您这样做),有一个很棒的 gem,叫做 Shoulda,它添加了单元测试宏来确保正确设置关系。我没有将它与内置的 Rails Test::Unit 一起使用,但 RSpec 示例看起来像:

describe Lead do
  it { should have_many(:emails) }
end

如果你真的想测试这种关系,你应该在规范中进行。从您的领导工厂中删除电子邮件关联并创建一个领导对象并尝试向其传递一些电子邮件对象,如下所示:

lead = Factory.build(:lead)
2.times do { lead.emails << Factory.build(:email, :lead => lead) }

那么它应该有几个电子邮件关联。但是,您应该对 ActiveRecord 抱有信心,并只测试 Rails 已经为您做的事情之外的事情。这就是应该派上用场的地方。

我的另一条评论是关于您的电子邮件 belongs_to 关系。由于您只是使用默认约定,因此 rails 会知道该怎么做。

class Email < ActiveRecord::Base
  belongs_to :lead
end

【讨论】:

  • 感谢您的回复,但是如果我想要一个名为lead_with_one_email 的工厂,因为我总是必须像您在上面那样创建它,该怎么办?当然,能够在工厂中这样做以减少重复创建代码是有意义的吗?看来这应该是可能的?
  • 如果您的所有潜在客户测试都需要至少一封电子邮件,那么这是一个问题。您应该能够独立于任何其他模型来测试您的领先模型。您可能需要为此使用模拟和存根。但是,如果您只有一个要通过电子邮件测试的测试子集,我会创建一个隔离此行为的组。在 Rspec 中,该组称为描述块或上下文块,它隔离了一些需要特定设置(例如电子邮件)的测试。
【解决方案2】:

这是一篇有趣的文章,可能会有所帮助:

http://icelab.com.au/articles/factorygirl-and-has-many-associations/

    FactoryGirl.define do
      factory :venue_with_gigs, :parent => :venue do
        after_create do |venue|
          FactoryGirl.create(:gig, :venue => venue)
        end
      end
    end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多