LoginSignup
11
8

More than 5 years have passed since last update.

FactoryGirlテストデータパターン生成方法

Posted at

呼び出し側で属性指定

呼び出し時にハッシュを渡すとデフォルトの値を上書きしてデータを生成できる

spec/factories/users.rb
FactoryGirl.define do
  factory :user do
    name "Isaac Newton"
    role "physicist"
    gender "male"
  end
end
user = FactoryGirl.create(:user, name: "Max Planck")
user.name
  # "Max Planck"
user.role
  # "physicist"
user.gender
  # "male"

ネストによるfactoryの継承(inheritance)

factoryをネストすると親の属性をすべて引き継いだ上で、子のfactoryで指定した属性を上書きしたデータを生成できる.

spec/factories/users.rb
FactoryGirl.define do
  factory :user do
    name "Isaac Newton"
    role "physicist"
    gender "male"

    factory :mathematician do
      role "mathematician"
    end

    factory :woman do
      gender "female"
    end
  end
end
user = FactoryGirl.create(:user)
user.name
  # "Isaac Newton"
user.role
  # "physicist"
user.gender
  # "male"

mathematician = FactoryGirl.create(:mathematician)
mathematician.name
  # "Isaac Newton"
mathematician.role
  # "mathematician"
mathematician.gender
  # "male"

woman = FactoryGirl.create(:woman)
woman.name
  # "Isaac Newton"
woman.role
  # "physicist"
woman.gender
  # "female"

parentによるfactoryの継承(inheritance)

ネストによるfactoryの継承はparent属性を使って以下のように書くこともできる.

spec/factories/users.rb
FactoryGirl.define do
  factory :user do
    name "Isaac Newton"
    role "physicist"
    gender "male"
  end

  factory :mathematician, parent: :user do
    role "mathematician"
  end

  factory :woman, parent: :user do
    gender "female"
  end
end
user = FactoryGirl.create(:user)
user.name
  # "Isaac Newton"
user.role
  # "physicist"
user.gender
  # "male"

mathematician = FactoryGirl.create(:mathematician)
mathematician.name
  # "Isaac Newton"
mathematician.role
  # "mathematician"
mathematician.gender
  # "male"

woman = FactoryGirl.create(:woman)
woman.name
  # "Isaac Newton"
woman.role
  # "physicist"
woman.gender
  # "female"

trait

継承はデータセットのファクトリ名のラベル(:userなど)が新たに作成されるのに対して、traitでは呼び出し側でtrait名を指定する. より柔軟にパターンを網羅させることができる.

spec/factories/users.rb
FactoryGirl.define do
  factory :user do
    name "Isaac Newton"
    role "physicist"
    gender "male"

    trait :mathematician do
      role "mathematician"
    end

    trait :professor do
      role "professor"
    end

    trait :father do
      role "father"
      gender "male"
    end

    trait :mother do
      role "mother"
      gender "female"
    end

    trait :man do
      gender "male"
    end

    trait :woman do
      gender "female"
    end
  end
end

呼び出し時に第2引数にtrait名を指定するとそのtraitブロックで属性を上書きしたデータが返る.

FactoryGirl.create(:user, :mathematician).role
  # "mathematician"

mother = FactoryGirl.create(:user, :mother)
mother.name
  # "Isaac Newton"
mother.role
  # "mother"
mother.gender
  # "female"

traitは複数指定でき、後に指定したtraitが前の属性を上書きする

user = FactoryGirl.create(:user, :father, :woman)
user.name
  # "Isaac Newton"
user.role
  # "father"
user.gender
  # "female"

traitを組み合わせたfactoryを作成

factory定義時にtraits属性で配列を渡せばtraitを組み合わせたfactoryを作成できる.

spec/factories/users.rb
FactoryGirl.define do
  factory :user do
    name "Isaac Newton"
    role "physicist"
    gender "male"

    trait :mathematician do
      role "mathematician"
    end

    trait :professor do
      role "professor"
    end

    trait :man do
      gender "male"
    end

    trait :woman do
      gender "female"
    end
  end

  factory :newton_mathematician, traits: [:mathematician], parent: :user
  factory :newton_professor, traits: [:professor], parent: :user
  factory :newton_woman_professor, traits: [:professor, :woman], parent: :user
end
user = FactoryGirl.create(:newton_mathematician)
user.name
  # "Isaac Newton"
user.role
  # "mathematician"
user.gender
  # "male"

user = FactoryGirl.create(:newton_woman_professor)
user.name
  # "Isaac Newton"
user.role
  # "professor"
user.gender
  # "female"

Conclusion

各属性のパターンはtraitで用意しそれらを組み合わせて、かつ継承を利用して基本的なデータパターンを網羅し、レアケースや汎用性のないデータは呼び出し側で用意する、といった使い方が有効そう.
なるべくテスト計画上重要なパターンをtraitで作成したい.

References

Environment

% ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux]

% gem list factory_girl

*** LOCAL GEMS ***

factory_girl (4.4.0)
factory_girl_rails (4.4.1)
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8