在 FactoryGirl 中使用 'default' 特征来避免不必要的关联创建

Using a 'default' trait in FactoryGirl to avoid unnecessary association creation

是否可以在 FactoryGirl 中定义默认特征?如果我像这样定义一个工厂(其中 question_response belongs_to 问题):

factory :question_response do
  question
  work_history

  trait :open do
    question { FactoryGirl.create :question, question_type: 'open' }
  end
end

当我做FactoryGirl.create :question_response, :open时,它会先创建一个默认问题,然后在特征内部创建另一个问题,这是不必要的操作。

理想情况下我想这样做:

factory :question_response do
  work_history

  trait :default do
    question { FactoryGirl.create :question, question_type: 'yes_no' }
  end

  trait :open do
    question { FactoryGirl.create :question, question_type: 'open' }
  end
end

然后做FactoryGirl.create :question会使用默认的trait,不过好像不行。

你的特征正在创建第二条记录,因为你有一个块正在创建一条记录:

trait :open do
  question { FactoryGirl.create :question, question_type: 'open' }
end

相反,您可以在设置了问题类型的问题上定义一个特征,然后让您的question_response使用该问题并将开放特征作为默认值。

factory.define :question do
  trait :open do
    question_type 'open'
  end
end

factory.define :question_response do
  association :question, :open
end

When I do FactoryGirl.create :question_response, :open it will first create a default question and then create another inside the trait

这不是真的。如果你用 question 指定特征,它会在创建之前覆盖工厂行为,这样它就不会创建默认问题。

我用 FactoryGirl v4.5.0 查了一下

以防万一其他人正在寻找 'default trait' 方案,这已通过 https://github.com/thoughtbot/factory_bot/issues/528#issuecomment-18289143

中的示例进行了讨论

基本上,您可以使用默认值定义特征,然后将其用于不同的工厂。然后您可以使用具有所需配置的适当工厂。

例如:

FactoryBot.define do
  trait :user_defaults do
    email { Faker::Internet.unique.email }
    username { Faker::Internet.unique.username }
    password { "test1234" }
  end

  factory :with_admin_role, class: User do
    user_defaults

    after(:create) do |user, _|
      user.add_role :admin
    end
  end

  factory :with_readonly_role, class: User do
    user_defaults

    after(:create) do |user, _|
      user.add_role :readonly
    end
  end
end