【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