工厂女孩嵌套工厂

hel*_*ion 13 ruby-on-rails-3 factory-bot

我有一个属于角色模型的帐户模型.

factory :role do
  name "student"
end

factory :account do
  user
  role
end
Run Code Online (Sandbox Code Playgroud)

第一个工厂创建一个名为"student"的角色.第二个工厂创建一个帐户,该帐户与在上一个工厂中创建的学生角色相关联.它也与用户相关联......这对于这个问题并不重要.

我有很多要测试的角色(管理员,学生,助理)......我不想在角色工厂中指定'学生'......这太静态了.如何指定创建帐户工厂时要创建的角色?喜欢:

  factory :account do
    user
    role_id { factory :role { name: "admin"} }
  end
Run Code Online (Sandbox Code Playgroud)

完成此任务的最佳方法是什么?

Chr*_*ald 31

如果你想要一个纯粹的FG解决方案,你可以使用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
Run Code Online (Sandbox Code Playgroud)

但是,您可以在创建工厂对象时覆盖工厂的属性.这样可以提高灵活性:

FactoryGirl.create(:account,
  :role => FactoryGirl.create(:role, :name => "student")
)
Run Code Online (Sandbox Code Playgroud)

由于这显然很冗长,我会创建一个小帮手方法:

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

然后在你的测试中:

let(:account) { account_as "student" }
Run Code Online (Sandbox Code Playgroud)

或者,您可以缩短角色生成器,以便您可以像以下一样使用它:

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

account = FactoryGirl.create :account, :role => role("student")
Run Code Online (Sandbox Code Playgroud)