2010-10-28 95 views
8

我有以下工廠:工廠女孩誤差的has_many關係

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

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 

當我通過早該運行該測試

我收到以下錯誤:

Factory::AttributeDefinitionError: Attribute already defined: emails

我完全被卡住這一點,任何人都可以點我在正確的方向。我正在使用factory_girl 1.3.2。

+0

的風格上看:工廠應該包含佔位符數據而已。所有這些對你來說都很重要,因爲使用它們會產生有效的潛在客戶,並且你應該假設附屬於潛在客戶的電子郵件的實際數量可能會發生變化。如果您的測試依賴於一定數量的線索,請從工廠建立線索,然後明確設置電子郵件。 – Matchu 2010-10-28 23:39:36

回答

9

我會建議不要加入的has_many關係數據到你的工廠。原因在於您的主要工廠現在依賴於填充此關聯關係,並且如果關聯發生變化,則會增加更多關聯並可能會導致一些混淆。

如果你想測試這種關係(我建議你這樣做),有一個叫Shoulda的巨大寶石添加了單元測試宏以確保關係設置正確。我還沒有與內置在Rails中的Test ::單位使用,但一個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 
+0

謝謝您的回覆,但是如果我想要一個名爲lead_with_one_email的工廠,因爲我總是需要像上面那樣創建它?在工廠能夠做到這一點是有道理的,以減少重複創建代碼? 這似乎應該是可能的? – dagda1 2010-10-29 04:53:56

+0

如果您的所有潛在客戶測試都需要至少一封電子郵件,那麼這是一個問題。您應該能夠獨立於任何其他型號測試您的主導模型。您可能需要爲此使用模擬和存根。但是,如果您只有一部分要通過電子郵件測試的測試,我會創建一個組來隔離此行爲。在Rspec中,這個組被稱爲描述或上下文塊,它隔離了一些需要特定設置(如電子郵件)的測試。 – 2010-10-29 05:26:05