traitとは
traitとは、FactoryBotで複数のサンプルデータを作成する際に使われるテクニック。
Factoryが複数ある場合、traitを使用することで記述の重複を減らすことができる。
traitの使い方
例えば、締め切りが異なる2つのプロジェクト(1週間前が締め切りのプロジェクトと昨日が締め切りのプロジェクト)があったとする。締め切り以外は共通のなので、そこだけtraitを使って記述すると、記入するコードも減る上に見やすくなる
FactoroyBot.define do
factory :project do
# 1週間前が締め切り
sequence(:name) { |n| "Test Project #{n}" }
description "Sample project for testing purposes"
due_on 1.week.from_now
association :owner
# 昨日が締め切り
trait :due_yesterday do
due_on 1.day.ago
end
end
end
なお定義方法は以下の通り。
FactoryBot.define do
factory :モデル名 do
trait :上記モデルを継承したインスタンスの属性値 do
#コード記入
end
end
end
実用例
tasks.rb
FactoryBot.define do
factory :task do
title { 'Task' }
status { rand(2) }
from = Date.parse("2019/08/01")
to = Date.parse("2019/12/31")
deadline { Random.rand(from..to) }
association :project
trait :done do
status { :done }
completion_date { Time.current.yesterday }
end
end
end
task_spec.rb
RSpec.describe 'Task', type: :system do
describe 'Task編集' do
let(:task_done) { create(:task, :done) }
it '既にステータスが完了のタスクのステータスを変更した場合、Taskの完了日が更新されないこと' do
visit edit_project_task_path(task_done.project, task_done)
select 'todo', from: 'Status'
click_button 'Update Task'
expect(page).to have_content('todo')
expect(page).not_to have_content(Time.current.strftime('%Y-%m-%d'))
expect(current_path).to eq project_task_path(task_done.project, task_done)
end
end
end