FactoryGirl creating objects in development environment
Asked Answered
S

4

7

When I boot up my rails console in development I see FactoryGirl creating objects. Clearly I'm doing it wrong, but what's the right way to do this? This code makes my tests work...

# tests/factories/board.rb
FactoryGirl.define do

    factory :word do
        sequence(:text) { |n| "FAKETEXT#{n}" }
    end

    factory :board do
        trait :has_words do
            words [
                FactoryGirl.create(:word, id: "514b81cae14cfa78f335e250"),
                FactoryGirl.create(:word, id: "514b81cae14cfa7917e443f0"),
                FactoryGirl.create(:word, id: "514b81cae14cfa79182407a2"),
                FactoryGirl.create(:word, id: "514b81cae14cfa78f581c534")
            ]
        end
    end

end

Note there's no mention of factory anything in any file in my config directory, so whatever loading is happening automatically by the gem. The relevant part of my Gemfile reads:

# Stuff not to use in production
group :development, :test do
    # Command-line debugger for development
    gem "debugger"

    # for unit testing - replace fixtures
    gem "factory_girl_rails"
end

So I could just take factory girl out of the development environment. But I think the fact that these records are being created before the factory is being used is a sign that I've written my factory incorrectly. But if you tell me the factory is written correctly, I'll just do that.

Statute answered 18/4, 2013 at 20:52 Comment(6)
is this code in spec/factories?Luffa
That code is in a factory file. Comment added with location.Statute
How is factory_girl listed in your gem file?Woodman
Updated with relevant part of Gemfile.Statute
Doesn't look like the factory is incorrect. Looks like there must be something calling it outside of your tests. How about doing a global text search of your app for FactoryGirl and see if it's called anywhere?Piet
@Piet the word "factory" never appears outside the test/ directory.Statute
S
7

Had the same problem. There are 2 ways to fix this,

1. Use FactoryGirl syntax to reference Factory within a Factory.

Replace FacotryGirl.create(:my_factory) with factory: :my_factory

More info on this, https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations

2. factory_girl :require => false in Gemfile

This causes Factories to generate objects on boot,

group :development, :test do  
  gem 'factory_girl_rails'
end  

Why? During Rails boot, Bundler requires all the gems in the development group, and it seems that FactoryGirl requires all their factory files. Requiring the factories evaluates the Ruby code, and thus, FactoryGirl.create(:my_factory) gets called.

This can be fixed by,

# Gemfile
group :development, :test do  
  gem 'factory_girl_rails', :require => false
end  

Just make sure to manually require factory_girl in your test environment, EG

# spec_helper
require 'factory_girl'
Sollows answered 31/8, 2013 at 19:45 Comment(0)
H
1

You just need to move factory girl out of the development environment.

I had the same issue, so I just did

group :test do
  gem 'faker'
  gem 'factory_girl_rails'
end

And works like a charm.

I'm not using those gems at all in development so its correct to just define them in test.

Harri answered 26/7, 2016 at 0:23 Comment(0)
G
0

for each factories or model, you have to put in different file

spec/factories/word_factory.rb
spec/factories/board_factory.rb

So the content of each factory, you can do something similar to this:

FactoryGirl.define do
  factory :board do
    word
    special_id
  end
end

when in your test folder such as models/board_spec.rb

you can create your object

let(:word) { FactoryGirl.create(:word)
let(:board) { FactoryGirl.create(:board, word: word) }

nt sure is this what you need,correct me if I'm wrong

Greywacke answered 21/4, 2013 at 1:32 Comment(1)
Moving the factory definitions to their own files didn't change anything. And I'm using test_unit not rspec so I'm not sure what to make of the rest of your advice.Statute
A
0

Assuming you want the words created when the factory is invoked and not at Rails startup, then you need to place the array of words inside a block, to wit:

trait :has_words do
        words do [
            FactoryGirl.create(:word, id: "514b81cae14cfa78f335e250"),
            FactoryGirl.create(:word, id: "514b81cae14cfa7917e443f0"),
            FactoryGirl.create(:word, id: "514b81cae14cfa79182407a2"),
            FactoryGirl.create(:word, id: "514b81cae14cfa78f581c534")
            ]
        end 
    end
Abukir answered 8/8, 2013 at 22:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.