2010-07-26 58 views
17

的問題類似的各實施例後回滾變化: http://rpheath.com/posts/411-how-to-use-factory-girl-with-rspecfactory_girl + rspec的似乎沒有此處描述

在短(shorten'd代碼):

spec_helper:

config.use_transactional_fixtures = true 
config.use_instantiated_fixtures = false 

factories.rb:

Factory.define :state do 
    f.name "NY" 
end 
在我的規格0
before(:each) do 
    @static_model = Factory(:state) # with validate uniqueness of state name 
end 

錯誤:

duplicate entry name "NY" etc.


問題:各規格例如之前 不應該RSPEC明確的數據庫,因此不扔重複錄入錯誤?

回答

40

的事情,我覺得關:

  • 你使用rake spec來運行你的測試套件:即構建了從無到有數據庫(以確保沒有被粘住)
  • 你使用,隨時隨地,一before (:all)?因爲無論你在before :all內創建了什麼內容,都應該在after :all中再次刪除,否則它會一直存在。
+1

重申nathanvda的建議,因爲我沒有足夠的業力投他的職位了起來:確保所有'之前(:所有)'塊是插入數據庫記錄有一個相應的'after(:all)'塊來銷燬它們! – dbalatero 2010-11-12 22:37:39

2

一些更可能的原因:

  • 仍然有states.yml夾具圍坐
  • 有人發揮各地在腳本/控制檯測試,忘了事後清理。
2

您也可能會發現,那是因爲你還沒有裹聲明:

describe "what it should do" do 
    @static_model = Factory(:state) # with validate uniqueness of state name 
end 

我發現,是解決這一問題的變化: Why isn't factory_girl operating transactionally for me? - rows remain in database after tests

+1

這是錯的。如果您創建了before(:each)或before(:all)塊之外的記錄,那麼您將在測試套件加載時創建記錄,而不是在執行時記錄。當然你會創造只有一次的記錄,但這是偶然的。如果你不想結束令人沮喪的可理解的代碼,請注意這一點。 – tothemario 2011-11-10 22:03:26

0

當您使用廠(:狀態)至極是一個捷徑Factory.create(:狀態),factory_girl會返回一個保存的對象。

改爲使用Factory.build(:state)。

0

Dude也許你的yaml裝置來自常規單元測試混入你的rspec?

2

Question: Shouldn't rspec clear database before each spec example and hence not throwing duplicate entry errors?

RSpec的與use_transactional_fixtures DatabaseCleaner或RSpec的Rails會只要清除DB作爲您在本例中本身產生的數據。 before :all do ... end被視爲例外,因爲數據在多個示例中保持不變。無論您在before :all中創建什麼,您都必須在after :all中刪除。

爲了刪除您自動創建的任何內容,請使用before :each do ... end。請注意,如果您有10個示例,則會創建和刪除相同的數據10次。 before :allbefore :each之間的差別就比較好解釋在這裏:rails rspec before all vs before each