2011-02-28 71 views
17

這是最近造成了一些挫折......AssociationTypeMismatch和FactoryGirl

看來,用我的黃瓜測試工廠,在某些情況下會導致AssociationTypeMismatch錯誤,如:預計

爲MyModel(#65776650)得到MyModel(#28190030)(ActiveRecord :: AssociationTypeMismatch)

這些似乎發生時有一個關聯引用 - 就像工廠創建的對象是不同的真實的。看到這個問題的更多細節:Cucumber duplicate class problem: AssociationTypeMismatch

我一直在逐漸改變工廠調用到真正的Model.create或mock_model調用。繼續使用工廠女孩會很高興......我想知道我可能做錯了什麼嗎?

謝謝

+2

請注意,如果您在控制檯窗口中使用'reload !'並且繼續創建工廠,也會發生這種情況。解決方案只是重新啓動您的控制檯會話。 – 2012-03-27 23:04:26

+0

@ Chrisbloom7提到的無需使用'reload!'的解決方案就可以工作。只是有點痛苦,繼續重新啓動軌控制檯 – 2015-11-10 17:50:57

回答

4

看來,如果的ActiveSupport卸載和重裝恆定的,你必須參考的情況發生。 我已經經歷使用RSpec /水豚一樣的,是什麼幫助是不同的東西的混合物:

  • 請確保您有在您的測試環境(配置/環境/ test.rb)設置爲false cached_classes
  • 在你gemspec,嘗試更換需要「factory_girl_rails」與「factory_girl」

我使用Spork(測試服務器),這似乎使這個東西越來越困難。 如果您正在使用測試服務器,請評估您是否應在gemspec中的factory_girl之後放置'::require => false'。

主題也包括在this google groups thread

請讓我們知道任何這幫助。

1

我取得了一些成功重裝廠定義嘗試這樣的事:

class Factory 
    def self.reload_definitions #:nodoc: 
    self.factories.clear 
    definition_file_paths.each do |path| 
     load("#{path}.rb") if File.exists?("#{path}.rb") 

     if File.directory? path 
     Dir[File.join(path, '*.rb')].each do |file| 
      load file 
     end 
     end 
    end 
    end 
end 
8

我有這樣的情況跟我on Rails的3.1.0 RC5,並得到了它的工作。

擴大喬納斯的答案。

你應該改變你的Gemfile是這樣的:

gem 'factory_girl', '~> 2.0.0', :require => false 
gem 'factory_girl_rails', '~> 1.1.0', :require => false 

,然後如果你使用的是叉勺,讓你的投機/ spec_helper.rb文件是這樣的:

Spork.each_run do 
require 'factory_girl' 
require 'factory_girl_rails' 
end 
+3

我也不得不把它放在我的Spork.each_run(在需求之前),使其工作:ActiveSupport :: Dependencies.clear #Reload模型 – NotDan 2012-01-18 04:56:49

+0

非常感謝。 Factory_girl_rails明確需要factory_girl。所以'gem'factory_girl_rails''和'require'factory_girl_rails''應該足夠了。 – iltempo 2012-08-19 11:14:05

2

出現這種情況因爲cache_classes是錯誤的,正如Spork所要求的那樣。水豚爲每個請求重新加載Rails類(或者,爲了正確,Rails的重新加載中間件,這不是正常測試所要求的),並且這使工廠變得怪異(究竟爲什麼,我不確定)。您可以重新加載它們,或者直接在Spork外運行您的Capybara規格。

所以你需要兩件事:只在Spork之外運行Capybara,並且只爲Spork設置cache_classes爲false。

運行僅水豚叉勺外,我有一個運行中的投機/請求規格叉勺和其他規格叉勺裏面這裏以外的Guardfile:

https://gist.github.com/1731900

然後,在config/environments/test.rb

config.cache_classes = !ENV['DRB'] 

你的水豚規格會慢一點,因爲他們需要啓動導軌,但一切都會正常工作。

4

如果您使用的是Spork,請確保在重新加載模型後重新加載工廠

E.g.

Spork.each_run 
    if Spork.using_spork? 
    print "Reloading models ... " 
    ActiveSupport::Dependencies.clear 
    puts "done" 

    print "Reloading factories ... " 
    FactoryGirl.reload 
    puts "done" 
    end 
end 
0

我遇到了同樣的問題,花了大概10個小時嘗試每個解決方案在這個線程和網絡上的其他地方。我開始剔除大量代碼,試圖讓它儘可能接近另一個我不能重現問題的應用程序。最後,我碰到了一些輔助功能,排在我spec_helper文件:

def sign_in(user)    
    visit signin_path    
    fill_in "Email", with: user.email 
    fill_in "Password", with: user.password 
    click_button "Sign in"  

    # Sign in when not using Capybara as well. 
    cookies[:remember_token] = user.remember_token if defined?(cookies) 
end 

一個sign_in幫手打算在雙方控制器和要求規範工作。它確實有點 - 只是與spork不同。當我刪除了水豚傭工的問題就解決了:

def sign_in(user)    
    cookies[:remember_token] = user.remember_token 
end 
1

我就遇到了這個問題,當我通過了「類」選項來我廠,是由其他工廠繼承:

factory :draft_resource, :class => Resource do 

factory :resource, :parent => :draft_resource do 

唯一我能找到的解決方案就是不要這樣做。