Factory already registered: user (FactoryGirl::Dup

2019-03-22 10:01发布

问题:

Description of problem: - I've setup factory_girl_rails however whenever I try and load a factory it's trying to load it multiple times.

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

The only other thing I've changed is: /config/initializers/generator.rb

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

GEMFILE

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

This seems to be a compatibility/environment issue that I can't seem to figure out. Any suggestions?

EDIT: here's my spec/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

回答1:

The gem factory_girl_rails should be required in the spec_helper.rb rather than the gemfile - it is possible that you are requiring FactoryGirl twice which is why you are getting the duplicate.

Try this in your gem file:

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

Then make sure that factory girl is required in the spec_helper with:

require 'factory_girl_rails'

By the way - you don't need both rspec and rpsec-rails in your gemfile. You can replace both with the following:

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

You need rspec in both groups so that the rake tasks will work in development and the core testing will work in test.



回答2:

I had the same problem recently. In my case one of the files in /factories had a _spec.rb ending (result of creative cp use). It was loading twice, first by rspec and then as a factory.



回答3:

I had this problem too. In my case there were two files with the same code, like this:

FactoryGirl.define do
  factory :user do
  end
end

One file was named "Useres.rb" and the other "User.rb" so I just deleted "Useres.rb" and fixed the error.



回答4:

Is there any chance you pasted this whole snippet for the support file from the config docs?

# 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

If you read the comments you'll see you only want one block or the other. I made this mistake and got the error stated in the question.



回答5:

Another possible reason is spare call of FactoryGirl.find_definitions. Try to remove find_definitions if found.



回答6:

Call FactoryGirl.define(:user) or FactoryGirl.find_definitions twice you also have this problem.

Try removing the second call or:

FactoryGirl.factories.clear
FactoryGirl.find_definitions  


回答7:

Make sure your individual factory files are not ending with _spec.



回答8:

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


Loading factory girl into a development console will do this too:

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

will raise a FactoryGirl::DuplicateDefinitionError on a sequence under Factory Girl v4.4.0.

It seems the sequences get handled differently within FG and simply wrapping all sequences in a rescue block will solve the issue.

For example:

  begin
    sequence :a_sequence do |n|
      n
    end
    sequence :another_sequence do |n|
      n*2
    end
  rescue FactoryGirl::DuplicateDefinitionError => e
    warn "#{e.message}"
  end


回答9:

I have the same the problem. What I do is move the spec/factories.rb to spec/factories/role.rb



回答10:

I renamed spec/factories as spec/setup_data and the problem gone. Try renaming the spec/factories to anything that suites you, should work.



回答11:

I had the same problem- make sure you aren't loading FactoryGirl a second time in your spec/support/env.rb file.



回答12:

I had same problem. This happens becouse of you using gem 'refinerycms-testing'? wich requires factory-girl, so you should commit this gem, or commit gem 'factory_girl_rails', don't use all of this gems.

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

or

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


回答13:

Please try following these steps

1) I looked for all occurrences of "factory_girl" from my RAILS_ROOT:

find . -name "*.rb" | xargs grep "factory_girl"

2) Because this was a full engine plugin "app" that I created via "rails plugin new --mountable", I had a file under RAILS_ROOT//lib/ called "engine.rb". It had:

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) I also had the following in my spec_helper.rb file:

Dir["#{File.dirname(FILE)}/factories/*/.rb"].each { |f| require f }

4) the g.fixture_replacement line in engine.rb and the Dir line in spec_helper.rb were initializing the factories twice. I commented out the one from spec_helper.rb and that fixed the problem.

Alternatively, you can leave in spec_helper.rb and comment out in engine.rb.

Both fixed the problem in my case.



回答14:

I had exactly the same problem. It occurs when you use the scaffold generator. It automatically creates a factory in test/factories/ So generally just deleting this file solve your issue



回答15:

I had the same problem, it turned out there was a default users.rb created inside the test/factories which was created by the rails g command. This file was causing the conflict. The error went away when I deleted the file.



回答16:

try to run

rake db:test:prepare



回答17:

I just found I was getting this answer when accidentally calling cucumber features. When I just called cucumber, the problem went away.



回答18:

I also ran with the same issue and commenting out a single line in spec_helper.rb file solved my problem.

Try commenting out this line from spec_helper.rb file and you should be good.

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


回答19:

I defined the same name factory at factories.rb, and I just found that someone else define the same factory below the directory of factories. So actually I can just use it without define another one.



回答20:

Replace the refinerycms-testing gem with rspec-rails and factory_girl_rails



回答21:

Check to see if you added factories through the model generator. My generator made a model and I added one to my main factory.rb file. Deleting the automatically generated ones worked for me.



回答22:

In my case,

First my co-worker has setup the project with factory_girl gem with

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

in rails_helper.

After some days, I replaced the gem with factory_girl_rails. Since this new gem also does that internally so factories were registered twice. This was causing the error.

Removed that line from rails_helper and it worked.



回答23:

I solved this because I was trying to create two factories. My feature spec included the line:

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

And then I used a sign_up(user) helper method:

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

Back to my feature spec, I called:

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

...

thus effectively trying to sign up a User that was already being created by the factory.

I altered the sign_up(user) to sign_in(user), and the helper to:

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 

now the user argument creates the User in the db due to the let! block and the sign_up(user) logs them in.

Hope this helps someone!

oh! and I also had to comment out:

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

as a lot of the other answers suggest.



回答24:

The strangest thing, I got this error with the following syntax error in the code:

before_validation :generate_reference, :on: :create

:on: was causing this error. How or why will remain a mystery.



回答25:

I resolved it by removing spec/factories/xxx.rb from command line:

rspec spec/factories/xxx.rb spec/model/xxx.rb # before
rspec spec/model/xxx.rb # after


回答26:

for me, this issue was coming because was using both gems

gem 'factory_bot_rails'
gem 'factory_girl_rails'

to solve I removed gem 'factory_bot_rails' from gem file. and also added require 'factory_girl' to spec/factories/track.rb file.

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

I hope this will help.



回答27:

Check that you don't have multiple factories with same name this is one of reasons which causes error

Attempting to define multiple factories with the same name will raise an error.