Accessing factory_girl factories in *other* factories
Asked Answered
P

3

20

I'm using the factory_girl plugin in my rails application. For each model, I have a corresponding ruby file containing the factory data e.g.

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  # t.user ???
end

I have lots of different types of users (already defined in the user factory). If I try the following though:

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  t.user Factory(:valid_user) # Fails
end

I get the following error:

# No such factory: valid_user (ArgumentError)

The :valid_user is actually valid though - I can use it in my tests - just not in my factories. Is there any way I can use a factory defined in another file in here?

Pedal answered 10/2, 2010 at 0:51 Comment(0)
I
32

You should use this code:

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  t.user { Factory(:valid_user) }
end

Wrapping the call in {} causes Factory Girl to not evaluate the code inside of the braces until the :valid_thing factory is created. This will force it to wait until the :valid_user factory has been loaded (Your example is failing because it is not yet loaded), it will also cause a new :valid_user to be created for each :valid_thing rather than having the same user for all :valid_thing's (Which is probably what you want).

Issuable answered 10/2, 2010 at 6:0 Comment(4)
This works well. Just know that the Factory(:valid_user) syntax has been deprecated; use FactoryGirl.create(:valid_user) instead.Householder
Using create(:valid_user) when I try to build(:valid_thing) will actually do a create, right? Is there a way to make this reference generic to be create/build depending on which is called?Jacobine
@Jacobine - No, build will notGastritis
The Factory(:valid_user) syntax is not just deprecated at this point; it's totally gone now, with no deprecation message. You can simply use create(:valid_user), without FactoryGirl.Chroma
P
4

Try using the association method like:

Factory.define :valid_thing, :class => Thing do |t|
  t.name 'Some valid thing'
  t.association :valid_user
end
Pseudocarp answered 10/2, 2010 at 3:13 Comment(1)
you can also do t.association :user, factory: :valid_userBesse
N
2

Potentially a new feature to Factory Girl judging by the age of the question, but if the name of your attribute in the Factory is the same as the name of the factory, simply calling the name of the attribute in your factory will populate it with the associated Factory generation.

FactoryGirl.define do
   factory :thing do
     user
   end
end

This should result in the user field looking for a factory with the same name and populating it from that.

Nellnella answered 1/3, 2017 at 7:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.