Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
590 views
in Technique[技术] by (71.8m points)

ruby on rails 3 - factory girl nested factory

I have an account model that belongs_to a role model.

factory :role do
  name "student"
end

factory :account do
  user
  role
end

The first factory creates a role named "student". The second factory creates an account that is associated to the student role that was created in the previous factory. It also is associated with a user...which is not important for this question.

I have many roles to be tested (admin, student, assistant)... I dont want to specify 'student' in the role factory...thats too static. How do I specify what role to create at the time the account factory is created? Like:

  factory :account do
    user
    role_id { factory :role { name: "admin"} }
  end

What is the best way to accomplish this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you want a purely FG solution, you could use Traits:

factory :account do
  user

  trait :student do
    association :role, :name => "student"
  end

  trait :admin do
    association :role, :name => "admin"
  end
end

FactoryGirl.create :account, :student
FactoryGirl.create :account, :admin

However, you can override the properties of the factory when you create the factory object. This allows for more flexibility:

FactoryGirl.create(:account,
  :role => FactoryGirl.create(:role, :name => "student")
)

Since this is obviously verbose, I'd create a little helper method:

def account_as(role, options = {})
  FactoryGirl.create(:account,
    options.merge(:role => FactoryGirl.create(:role, :name => "student"))
  )
end

Then in your tests:

let(:account) { account_as "student" }

Alternately, you could just shorten up your role generator so you could use it like:

def role(role, options = {})
  FactoryGirl.create :role, options.merge(:name => role)
end

account = FactoryGirl.create :account, :role => role("student")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...