【RSpec】 管理者・一般ユーザーを分けてテストデータを作成する
実装したいこと
管理者と一般ユーザーで権限が違うため、それぞれのテストデータを作成したい。
trait
トレイトを使う。 属性を予めセットして定義できる機能。
trait:A distinguishing quality or characteristic, typically one belonging to a person.
FactoryBot.define do
factory :user do
sequence(:name) { |n| "general-#{n}" } #sequenceで一意のデータを生成する。
password { 'password' }
password_confirmation { 'password' }
role { :general } #default値を設定する。
trait :admin do
sequence(:name) { |n| "admin-#{n}" }
role{ :admin }
end
trait :general do
sequence(:name) { |n| "general-#{n}" }
role{ :general }
end
end
end
traitの使い方がいまいち理解できてなかったのですが、
デフォルトでは全ての属性をセットしておく。→ traitは指定したい属性だけ切り取ってセットする。
っていうことですね。
マクロを使ってログイン機能だけセットする
module LoginMacro
def login_as(user)
visit login_path
fill_in 'user[name]', with: user.name
click_button '次へ'
fill_in 'user[password]', with: 'password' #user.passwordはnil
click_button 'ログイン'
end
end
※ rails_helper.rbで読み込み設定をしておきます。
(略)
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } #support以下を読み込む
RSpec.configure do |config|
(略)
config.include FactoryBot::Syntax::Methods #FacctoryBotの記述を省略できる
config.include LoginMacros #LoginMacrosを読み込む
end
module ? macros?
以前もログイン機能の切り出しはしたのですが、そのときはLoginModuleとしていました。
Macro Moduleどっち?…と疑問に思ったので講師の方に質問したところ、慣例で現場によって異なるのでどっちでもいいとのことでした。
System Spec
require 'rails_helper'
RSpec.describe "AdiminArticlesPreviews", type: :system do
let(:admin) { create :user, :admin }
describe '記事作成画面で画像ブロックを追加' do
context '画像なしで投稿する' do
it 'プレビューが正常に表示される' do
login_as(admin)
(略)
switch_to_window(windows.last) #windowを切り替え、最後のwindowを指定
expect(page).to have_content('test')
end
end
end
end
let(:admin) { create :user, :admin }
let(定義名) { 内容 }です。
{ create :user, :admin }の:admin部分で、さっき定義したtraitを使っています。
login_as(admin)
マクロで定義したログイン用のメソッドを使っています。
引数に、letで作成したadminを渡して、管理者としてログインしています。
System Specの命名について
Controllerが、admin/articles/previews_controllerのように名前空間で分かれているとき、どうやってファイル名をつけたらいいのかな?って思ったけど、普通に、admin_articles_previews_spec.rbとするみたい。
NGコード
最初に私が実装したコードを反省用に残しておく。一応動くけど酷い、汚い。。
describe,contextとbeforeをなんとなくで使っているので勉強します
require 'rails_helper'
RSpec.describe "Previews", type: :system do
let(:admin) { create(:user, :admin) }
before{ login_as(admin) }
describe '記事の画像投稿機能' do
before do
click_link '記事'
click_link '新規作成'
fill_in 'タイトル', with: 'test'
click_button '登録する'
click_link 'ブロックを追加する'
click_link '画像'
end
context '画像なしで投稿する' do
it 'プレビューが見れること' do
click_link 'プレビュー'
switch_to_window(windows.last)
expect(page).to have_content('test')
end
end
end
end
参考
トレイトについて 『everydayRails』P64