AssociationTypeMismatch和FactoryGirl

这最近引起了一些挫折……

似乎在我的黄瓜测试中使用工厂,在某些情况下会导致AssociationTypeMismatch错误,例如:

MyModel(#65776650)期待,得到MyModel(#28190030)(ActiveRecord :: AssociationTypeMismatch)

这些似乎在存在关联引用时发生 – 就好像Factory创建的对象与真实对象不同。 有关更多详细信息,请参阅此问题: Cucumber重复类问题:AssociationTypeMismatch

我一直在逐渐将Factory调用更改为真正的Model.create或mock_model调用。 继续使用工厂女孩会很好……我想知道是否有什么我可能做错了?

谢谢

我在Rails 3.1.0 rc5上发生了这种情况,并让它运行起来。

扩展乔纳斯的答案。

您应该将Gemfile更改为:

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

然后,如果您使用Spork,请使您的spec / spec_helper.rb文件如下所示:

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

如果ActiveSupport卸载并重新加载您有引用的常量,似乎会发生这种情况。 我和Rspec / Capybara有过相同的经历,并且有很多不同之处:

  • 确保在测试环境中将cached_classes设置为false(config / environments / test.rb)
  • 在您的gemspec中,尝试将’factory_girl_rails’替换为’factory_girl’

我正在使用Spork (测试服务器),这似乎使这些东西越来越难。 如果您使用的是测试服务器,请评估是否应在gemspec中的factory_girl之后添加’,:require => false’。

这个主题也包含在这个谷歌组线程中

如果有任何帮助,请告诉我们。

如果您正在使用Spork,请确保在重新加载模型重新加载工厂。

例如

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

发生这种情况是因为cache_classes是假的,正如Spork所要求的那样。 Capybara为每个请求重新加载Rails类(或者,正确的是,Rails的重新加载器中间件没有,正常测试没有调用),这使工厂变得怪异(确切地说,为什么,我不确定)。 你可以重新加载它们,或者只是在Spork之外运行你的Capybara规格。

所以你需要两件事:只在Spork之外运行Capybara,并且只为Spork设置cache_classes为false。

为了只在Spork之外运行Capybara,我有一个Guardfile,可以在Spork之外的规范/请求中运行规范,以及Spork内部的其他规范:

https://gist.github.com/1731900

然后,在config/environments/test.rb

 config.cache_classes = !ENV['DRB'] 

你的Capybara规格会慢一点,因为他们需要启动rails,但一切都会正常工作。

我在重新加载Factory定义方面取得了一些成功,请尝试以下方法:

 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 

当我将“class”选项传递给我的工厂时,我遇到了这个问题,这个选项是由其他工厂inheritance的:

 factory :draft_resource, :class => Resource do factory :resource, :parent => :draft_resource do 

我能找到的唯一解决办法就是不要这样做。

我遇到了同样的问题,大概花了十个小时尝试这个线程和网络上其他地方的每个解决方案。 我开始掏出大量的代码试图让它接近我的另一个应用程序,我无法重现这个问题。 最后,我在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