47

问题描述: - 我已经设置了 factory_girl_rails 但是每当我尝试加载工厂时,它都会尝试多次加载它。

Environment:
- rails (3.2.1)
- factory_girl (2.5.2)
- factory_girl_rails (1.6.0)
- ruby-1.9.3-p0 [ x86_64 ]

> rake spec --trace
** Execute environment
-- Creating User Factory
-- Creating User Factory
rake aborted!
Factory already registered: user

我唯一改变的是:/config/initializers/generator.rb

Rails.application.config.generators do |g|
  g.test_framework = :rspec
  g.fixture_replacement :factory_girl
end

宝石文件

gem 'rails', '3.2.1'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'
gem 'devise'
gem 'haml-rails'

group :development do
  gem 'hpricot'
  gem 'ruby_parser'
  gem "rspec-rails"
end

group :test do
  gem "rspec"
  gem 'factory_girl_rails'
end

gem 'refinerycms-core',       :git => 'git://github.com/resolve/refinerycms.git'
gem 'refinerycms-dashboard',  :git => 'git://github.com/resolve/refinerycms.git'
gem 'refinerycms-images',     :git => 'git://github.com/resolve/refinerycms.git'
gem 'refinerycms-pages',      :git => 'git://github.com/resolve/refinerycms.git'
gem 'refinerycms-resources',  :git => 'git://github.com/resolve/refinerycms.git'
gem 'refinerycms-settings',   :git => 'git://github.com/resolve/refinerycms.git'

group :development, :test do
  gem 'refinerycms-testing',  :git => 'git://github.com/resolve/refinerycms.git'
end

gem 'refinerycms-inventories', :path => 'vendor/engines'

FactoryGirl.define do
  factory :role do
    title "MyString"
  end
end

这似乎是我似乎无法弄清楚的兼容性/环境问题。有什么建议么?

编辑:这是我的规范/spec_helper.rb:

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
#require 'factory_girl_rails'

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
### Mock Framework
  #
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
  #
  # config.mock_with :mocha
  # config.mock_with :flexmock
  # config.mock_with :rr

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  #config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true

  # If true, the base class of anonymous controllers will be inferred
  # automatically. This will be the default behavior in future versions of
  # rspec-rails.
  config.infer_base_class_for_anonymous_controllers = false
end
4

27 回答 27

37

gemfactory_girl_rails应该在spec_helper.rb而不是 gemfile 中是必需的 - 您可能需要 FactoryGirl 两次,这就是您获得副本的原因。

在你的 gem 文件中试试这个:

group :test do
  gem "rspec"
  gem 'factory_girl_rails', :require => false
end

然后确保 spec_helper 中需要工厂女孩:

require 'factory_girl_rails'

顺便说一句 - 你不需要在你的 gemfile 中rspecrpsec-rails您可以将两者都替换为以下内容:

group :development, :test do
  gem 'rspec-rails'
end

您在两个组中都需要 rspec,以便 rake 任务将在开发中工作,而核心测试将在测试中工作。

于 2012-02-17T01:11:49.870 回答
23

我最近遇到了同样的问题。在我的例子中,/factories 中的一个文件有一个 _spec.rb 结尾(创造性 cp 使用的结果)。它加载了两次,首先是 rspec,然后是工厂。

于 2012-04-29T03:00:09.627 回答
16

您是否有机会将整个片段粘贴到配置文档中的支持文件中?

# RSpec
# spec/support/factory_girl.rb
RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
end

# RSpec without Rails
RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods

  config.before(:suite) do
    FactoryGirl.find_definitions
  end
end

如果您阅读评论,您会发现您只想要一个块或另一个块。我犯了这个错误并得到了问题中所述的错误。

于 2016-12-10T20:41:10.257 回答
15

我也有这个问题。就我而言,有两个文件具有相同的代码,如下所示:

FactoryGirl.define do
  factory :user do
  end
end

一个文件被命名为“Useres.rb”,另一个被命名为“User.rb”,所以我只是删除了“Useres.rb”并修复了错误。

于 2012-08-29T13:22:15.647 回答
11

打电话FactoryGirl.define(:user)FactoryGirl.find_definitions两次你也有这个问题。

尝试删除第二个电话或:

FactoryGirl.factories.clear
FactoryGirl.find_definitions  
于 2013-05-14T06:46:25.247 回答
9

另一个可能的原因是备用电话FactoryGirl.find_definitions。如果找到,请尝试删除 find_definitions。

于 2013-01-23T21:26:19.320 回答
5

确保您的各个工厂文件不以_spec.

于 2012-10-24T08:24:26.410 回答
2

https://github.com/thoughtbot/factory_girl/issues/638


将 factory girl 加载到开发控制台中也会这样做:

require 'factory_girl_rails'; reload!; FactoryGirl.factories.clear; FactoryGirl.find_definitions

FactoryGirl::DuplicateDefinitionError在 Factory Girl v4.4.0 下的序列上引发 a。

似乎序列在 FG 中的处理方式不同,只需将所有序列包装在救援块中即可解决问题。

例如:

  begin
    sequence :a_sequence do |n|
      n
    end
    sequence :another_sequence do |n|
      n*2
    end
  rescue FactoryGirl::DuplicateDefinitionError => e
    warn "#{e.message}"
  end
于 2014-03-26T12:32:56.423 回答
1

我有同样的问题。我所做的是将 spec/factories.rb 移动到 spec/factories/role.rb

于 2012-02-29T09:01:47.280 回答
1

我遇到了同样的问题——确保你没有在你的 spec/support/env.rb 文件中再次加载 FactoryGirl。

于 2012-07-05T19:33:02.113 回答
1

我将 spec/factories 重命名为 spec/setup_data,问题就消失了。尝试将规范/工厂重命名为适合您的任何东西,应该可以。

于 2012-03-16T10:54:42.140 回答
1

我有同样的问题。这是因为您使用了 gem 'refinerycms-testing'?这需要工厂女孩,所以你应该提交这个 gem,或者提交 gem 'factory_girl_rails',不要使用所有这些 gem。

    #gem 'refinerycms-testing', '~> 2.0.9', :group => :test
    gem 'factory_girl_rails', :group => :test

或者

    #gem 'factory_girl_rails', :group => :test
    gem 'refinerycms-testing', '~> 2.0.9', :group => :test 
于 2013-02-26T15:35:36.867 回答
1

请尝试按照以下步骤操作

1) 我从我的 RAILS_ROOT 中查找所有出现的“factory_girl”:

寻找 。-名称“*.rb”| xargs grep "factory_girl"

2)因为这是我通过“rails plugin new --mountable”创建的完整引擎插件“app”,所以我在RAILS_ROOT//lib/下有一个名为“engine.rb”的文件。它有过:

config.generators do |g|
  g.test_framework      :rspec,        :fixture => false
  g.fixture_replacement :factory_girl, :dir => 'spec/factories'
  g.assets false
  g.helper false
end

3) 我的 spec_helper.rb 文件中还有以下内容:

目录["#{File.dirname( FILE )}/factories/* / .rb"].each { |f| 要求 f }

4) engine.rb 中的 g.fixture_replacement 行和 spec_helper.rb 中的 Dir 行正在初始化工厂两次。我注释掉了 spec_helper.rb 中的那个,这解决了这个问题

或者,您可以保留在 spec_helper.rb 中并在 engine.rb 中注释掉。

两者都解决了我的问题。

于 2013-03-26T03:41:41.373 回答
1

尝试运行

耙分贝:测试:准备

于 2017-06-24T19:23:51.890 回答
1

我有完全相同的问题。当您使用脚手架生成器时会发生这种情况。它会自动在 test/factories/ 中创建工厂所以通常只需删除此文件即可解决您的问题

于 2015-07-16T21:26:03.860 回答
1

我遇到了同样的问题,结果发现里面有一个由命令users.rb创建的默认值。该文件导致了冲突。当我删除文件时,错误消失了。test/factoriesrails g

于 2017-03-24T06:59:27.927 回答
0

我刚刚发现我在不小心打电话时得到了这个答案cucumber features。当我刚打电话cucumber时,问题就消失了。

于 2012-10-19T00:38:18.447 回答
0

用 rspec-rails 和 factory_girl_rails 替换炼油厂cms-testing gem

于 2014-01-14T20:09:15.463 回答
0

我也遇到了同样的问题,并在 spec_helper.rb 文件中注释掉一行解决了我的问题。

尝试从 spec_helper.rb 文件中注释掉这一行,你应该会很好。

Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
于 2013-09-17T23:17:40.893 回答
0

我在factories.rb定义了同名工厂,刚刚发现有人在工厂目录下定义了同名工厂。所以实际上我可以直接使用它而不定义另一个。

于 2014-01-07T08:43:34.857 回答
0

检查您是否通过模型生成器添加了工厂。我的生成器制作了一个模型,并在我的主 factory.rb 文件中添加了一个模型。删除自动生成的对我有用。

于 2014-01-21T19:09:37.307 回答
0

我解决了这个问题,因为我试图创建两个工厂。我的功能规范包括以下行:

let!(:user) { create(:user) }

然后我使用了一个 sign_up(user) 辅助方法:

def sign_up(user)
  visit '/users/sign_up'
  fill_in 'Email', with: user.email
  fill_in 'Password', with: user.password
  fill_in 'Password confirmation', with: user.password_confirmation
  click_button 'Sign up'
end

回到我的功能规范,我打电话给:

context 'logging out' do
  before do
    sign_up(user)
  end

...

因此有效地尝试注册一个已经由工厂创建的用户。

我将 sign_up(user)tosign_in(user)和 helper 更改为:

def sign_in(user)
  visit '/users/sign_in'
  fill_in 'Email', with: user.email
  fill_in 'Password', with: user.password
  click_button 'Log in'
end 

现在,user由于let!阻塞,参数在数据库中创建了用户并将sign_up(user)它们登录。

希望这对某人有帮助!

哦!我还不得不评论一下:

Dir[Rails.root.join('spec/factories/**/*.rb')].each { |f| require f }

正如许多其他答案所暗示的那样。

于 2016-11-10T16:18:36.413 回答
0

对我来说,这个问题来了,因为同时使用了两个宝石

gem 'factory_bot_rails'
gem 'factory_girl_rails'

解决我gem 'factory_bot_rails'从 gem 文件中删除的问题。并添加require 'factory_girl'spec/factories/track.rb文件中。

if Rails.env.test?
    require 'factory_girl'
    FactoryGirl.define do
      factory :track do
            id 1
            name "nurburgring"
            surface_type "snow"
            time_zone "CET"
       end
    end

我希望这将有所帮助。

于 2018-08-27T18:35:50.570 回答
0

就我而言,

首先,我的同事使用factory_girlgem设置了项目

Dir[Rails.root.join('spec/factories/**/*.rb')].each { |f| require f }

rails_helper.

几天后,我用factory_girl_rails. 由于这个新的 gem 在内部也是这样做的,所以工厂注册了两次。这是导致错误的原因。

从中删除该行rails_helper并且它起作用了。

于 2016-09-05T08:37:59.453 回答
0

最奇怪的是,我得到了这个错误,代码中出现以下语法错误:

before_validation :generate_reference, :on: :create

:on:导致此错误。如何或为什么将仍然是一个谜。

于 2017-10-09T09:51:31.653 回答
0

spec/factories/xxx.rb我通过从命令行中删除来解决它:

rspec spec/factories/xxx.rb spec/model/xxx.rb # before
rspec spec/model/xxx.rb # after
于 2018-01-19T10:48:27.873 回答
-1

检查您是否没有多个具有相同名称的工厂,这是导致错误的原因之一

尝试定义多个具有相同名称的工厂将引发错误。

于 2013-02-01T11:52:03.427 回答