2012-02-17 59 views
49

我正在使用Factory Girl在我的模型/單元測試中爲一個組創建兩個實例。我測試的模型來檢查調用根據到期屬性按以下.current僅返回「當前」組......繞過我的模型驗證的工廠女孩​​創建

describe ".current" do 
    let!(:current_group) { FactoryGirl.create(:group, :expiry => Time.now + 1.week) } 
    let!(:expired_group) { FactoryGirl.create(:group, :expiry => Time.now - 3.days) } 

    specify { Group.current.should == [current_group] } 
    end 

我的問題是,我已經得到驗證模型檢查新組的到期時間是在今天的日期之後。這在下面提出了驗證失敗。

1) Group.current 
    Failure/Error: let!(:expired_group) { FactoryGirl.create(:group, :expiry => Time.now - 3.days) } 
    ActiveRecord::RecordInvalid: 
     Validation failed: Expiry is before todays date 

有沒有辦法在使用Factory Girl創建時強制創建組或驗證驗證?

回答

62

這不是非常具體的FactoryGirl,而是通過save(:validate => false)保存模型時,你總是可以繞過驗證:

describe ".current" do 
    let!(:current_group) { FactoryGirl.create(:group) } 
    let!(:old_group) { 
    g = FactoryGirl.build(:group, :expiry => Time.now - 3.days) 
    g.save(:validate => false) 
    g 
    } 

    specify { Group.current.should == [current_group] } 
end 
+0

這正是我一直在尋找,謝謝! – Norto23 2012-02-17 03:39:20

+0

查看Jason Denney的答案以獲得更好的解決方案。 – 2017-12-12 18:46:54

5

對於這個特定的日期baesd驗證的情況下,你也可以使用timecop寶石暫時改變時間模擬過去創建的舊記錄。

1

根據您的情況,您可以將驗證更改爲僅在更新時發生。例如::validates :expire_date, :presence => true, :on => [:update ]

46

我更喜歡https://github.com/thoughtbot/factory_girl/issues/578這個解決方案。

裏面的工廠:

to_create {|instance| instance.save(validate: false) } 
+4

這是一個比公認的更優雅的解決方案。 – 2016-03-04 04:19:31

+3

請記住,如果你爲通用工廠做了這個工作,那麼當你在該工廠創建時,你會跳過驗證。最好只在一個子工廠(或特質)上使用這種技術。 – tgf 2017-07-05 00:01:52

+0

你幾乎可以肯定要把這個特點。請參閱下面的Tim Scott的答案。 – 2017-12-12 18:48:22

3
foo = build(:foo).tap{ |u| u.save(validate: false) } 
6

這是一個壞主意,跳過默認驗證工廠。發現一些頭髮會被拉出來。

的最好的方式,我認爲:

trait :skip_validate do 
    to_create {|instance| instance.save(validate: false)} 
end 

然後在您的測試:

create(:group, :skip_validate, expiry: Time.now + 1.week) 
+0

這是解決這個問題的最好方法! – 2018-03-07 17:03:27