【RSpec】Factory_Botについて(パート2)

はじめに

 以前、【RSpec】Factory_botについてで基本的なFacotoryの使い方を説明しました。今回はさらに発展的なFactoryBotの使い方を紹介していきます。

基本的なファクトリー定義

  • 直接値を入れる
  • 値を動的に生成する
  • シーケンスを使用する
  • アソシエーションを定義する
FactoryBot.define do
  factory :user do
  first_name { "John" } #直接値を入れる
     last_name { "Doe" }  #直接値を入れる
  date_of_birth { 18.years.ago } # 値を動的に生成する
     sequence(:email) { |n| "test#{n}@example.com" } # シーケンスを使用
     assosiation :organization # Organizationへのアソシエーション
  end
end

buildcreate

*buildで十分な時はbuildを使用する

users = build_list(:user, 2)
users = create_list(:user, 2)

traitを使用し、条件の異なるファクトリーを定義

FactoryBot.define do
  factory :article do
    sequence(:title) { |n| "title-#{n}" }
    sequence(:slug) { |n| "slug-#{n}" }
  end

  trait :draft do
    state { :draft }
  end

  trait :future do
    published_at { Time.current.tomorrow }
    state { :publish_wait }
  end

  trait :past do
    published_at { Time.current.yesterday }
    state { :published }
  end

インスタンス生成時に、traitを指定、複数指定することもできます。

transientやcallbackを組み合わせてアソシエーション先のデータを生成

transientはモデルの属性以外のデータをファクトリに含めることができます。

after(:build)はコールバックでarticleインスタンスが生成された後に実行されます。

trait :with_author do
    #articleモデルの属性以外のデータをファクトリに含める
    transient do
      sequence(:author_name) { |n| "test_author_name_#{n}" }
      sequence(:tag_slug) { |n| "test_author_slug_#{n}" }
    end


    after(:build) do |article, evaluator|  #article作成して、その記事のauthorをbuildしている。
   # belongs_to :authorは定義済 
      article.author = build(:author, name: evaluator.author_name, slug: evaluator.tag_slug) #上記の変数を使用
    end
  end

参考文献

FactoryBotを使う時に覚えておきたい、たった5つのこと