rspecによるrailsテスト入門 第六章 高度なコントローラスペック

19
EveryDayRailsRSpec リューノス読書会 2015-10-26 第六章 高度なコントローラスペック

Upload: akai

Post on 15-Apr-2017

224 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

EveryDayRailsRSpecリューノス読書会

2015-10-26

第六章

高度なコントローラスペック

Page 2: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

@__akai16歳JK(大嘘)

Page 3: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

コントローラの基礎はマスターしましたか?

Page 4: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

……あたぼうよ!

Page 5: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

第六章 概要

● ロールを分けてテストする– ロール…… 管理者や一般ユーザー、ゲストなど、アカウント

の切り分け

Page 6: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

ロールのテストをするときに考えること

● 認証の処理のシミュレート– 閲覧者(ユーザ)はログインしているのかどうか– ユーザの持つロールはなにか

※ 本書のアプリでは、ユーザとしてログインしなければ、連絡先の追加や編集はできず、管理者ユーザでなければ他のユーザの追加ができない

Page 7: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

アイツとはヨかったケド、アイツはダメ……

Page 8: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

ユーザ作成ファクトリ 1 FactoryGirl.define do

2 factory :user do

3 email { Faker::Internet.email }

4 password 'secret'

5 password_confirmation 'secret'

6 factory :admin do

7 admin true

8 end

9 end

10 end

spec/factories/users.rb

Page 9: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

ユーザ作成ファクトリ 1 FactoryGirl.define do

2 factory :user do

3 email { Faker::Internet.email }

4 password 'secret'

5 password_confirmation 'secret'

6 factory :admin do

7 admin true

8 end

9 end

10 end

● create(:user)でユーザが作成できるようになる– 子ファクトリにadminフラグ

を追加してあるので、管理者ロールを付加したユーザも作成可

spec/factories/users.rb

Page 10: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

かんたんにたくさんふえるね!

factory! factory!

factory!

factory!

Page 11: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

管理者がアクセスした場合のテスト 1 describe "administrator access" do 2 before :each do 3 user = create(:admin) 4 session[:user_id] = user.id 5 end 6 describe 'GET #index' do 7 # params[:letter] がある場合 8 context 'with params[:letter]' do 9 # 指定された文字で始まる連絡先を配列に集めること 10 it "populates an array of contacts starting with the letter" do 11 smith = create(:contact, lastname: 'Smith') 12 jones = create(:contact, lastname: 'Jones') 13 get :index, letter: 'S' 14 expect(assigns(:contacts)).to match_array([smith]) 15 end 16 # :index テンプレートを表示すること 17 it "renders the :index template" do 18 get :index, letter: 'S' 19 expect(response).to render_template :index 20 end 21 end 22 # params[:letter] がない場合 23 context 'without params[:letter]' do 24 # すべての連絡先を配列に集めること 25 it "populates an array of all contacts" do 26 smith = create(:contact, lastname: 'Smith') 27 jones = create(:contact, lastname: 'Jones') 28 get :index 29 expect(assigns(:contacts)).to match_array([smith, jones]) 30 end

30 end 31 # :index テンプレートを表示すること 32 it "renders the :index template" do 33 get :index 34 expect(response).to render_template :index 35 end 36 end 37 end 38 describe 'GET #show' do 39 # @contact に要求された連絡先を割り当てること 40 it "assigns the requested contact to @contact" do 41 contact = create(:contact) 42 get :show, id: contact 43 expect(assigns(:contact)).to eq contact 44 end 45 # :show テンプレートを表示すること 46 it "renders the :show template" do 47 contact = create(:contact) 48 get :show, id: contact 49 expect(response).to render_template :show 50 end 51 end 52 # などなど ... 53 end

spec/controllers/contacts_controller_spec.rb

Page 12: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

管理者がアクセスした場合のテスト 1 describe "administrator access" do 2 before :each do 3 user = create(:admin) 4 session[:user_id] = user.id 5 end 6 describe 'GET #index' do 7 # params[:letter] がある場合 8 context 'with params[:letter]' do 9 # 指定された文字で始まる連絡先を配列に集めること 10 it "populates an array of contacts starting with the letter" do 11 smith = create(:contact, lastname: 'Smith') 12 jones = create(:contact, lastname: 'Jones') 13 get :index, letter: 'S' 14 expect(assigns(:contacts)).to match_array([smith]) 15 end 16 # :index テンプレートを表示すること 17 it "renders the :index template" do 18 get :index, letter: 'S' 19 expect(response).to render_template :index 20 end 21 end 22 # params[:letter] がない場合 23 context 'without params[:letter]' do 24 # すべての連絡先を配列に集めること 25 it "populates an array of all contacts" do 26 smith = create(:contact, lastname: 'Smith') 27 jones = create(:contact, lastname: 'Jones') 28 get :index 29 expect(assigns(:contacts)).to match_array([smith, jones]) 30 end

30 end 31 # :index テンプレートを表示すること 32 it "renders the :index template" do 33 get :index 34 expect(response).to render_template :index 35 end 36 end 37 end 38 describe 'GET #show' do 39 # @contact に要求された連絡先を割り当てること 40 it "assigns the requested contact to @contact" do 41 contact = create(:contact) 42 get :show, id: contact 43 expect(assigns(:contact)).to eq contact 44 end 45 # :show テンプレートを表示すること 46 it "renders the :show template" do 47 contact = create(:contact) 48 get :show, id: contact 49 expect(response).to render_template :show 50 end 51 end 52 # などなど ... 53 end

spec/controllers/contacts_controller_spec.rb

Page 13: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

なにをしたの?● 既存のテスト項目を

describe "administrator access" do~end

で囲み、直後にbeforeブロックを追加– テスト実行前に管理者アカウ

ントを作成し、ログインをシミュレーション

1 describe "administrator access" do

2 before :each do

3 user = create(:admin)

4 session[:user_id] = user.id

5 end

spec/controllers/contacts_controller_spec.rb

Page 14: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

一般ユーザのテスト● 管理者ロールとほぼ同じ 1 describe "user access" do

2 before :each do

3 user = create(:user)

4 session[:user_id] = user.id

5 end

spec/controllers/contacts_controller_spec.rb

Page 15: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

ゲストユーザのテスト 1 describe "guest access" do

2 # GET #index と GET #show の example は管理者と

3 # ユーザーの example と同じ

4 describe 'GET #new' do

5 # ログインを要求すること

6 it "requires login" do

7 get :new

8 expect(response).to redirect_to login_url

9 end

10 end

11 describe 'GET #edit' do

12 # ログインを要求すること

13 it "requires login" do

14 contact = create(:contact)

15 get :edit, id: contact

16 expect(response).to redirect_to login_url

17 end

18 end

19 describe "POST #create" do

20 # ログインを要求すること 21 it "requires login" do

22 post :create, id: create(:contact),

23 contact: attributes_for(:contact)

24 expect(response).to redirect_to login_url

25 end

26 end

27 describe 'PATCH #update' do

28 # ログインを要求すること 29 it "requires login" do

30 put :update, id: create(:contact),

31 contact: attributes_for(:contact)

32 expect(response).to redirect_to login_url

33 end

34 end

35 describe 'DELETE #destroy' do

36 # ログインを要求すること 37 it "requires login" do

38 delete :destroy, id: create(:contact)

39 expect(response).to redirect_to login_url

40 end

41 end

42 end spec/controllers/contacts_controller_spec.rb

Page 16: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

ゲストユーザの仕様

● ゲストはコントローラの処理を実行できない– 代わりにlogin_urlへリダイレクトされる

● コントローラのbefore_actionで実装済

Page 17: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

その他のロールによる認可 1 describe 'user access' do

2 before :each do

3 @user = create(:user)

4 session[:user_id] = @user.id

5 end

6 describe 'GET #index' do

7 # ユーザーを @users に集めること

8 it "collects users into @users" do

9 user = create(:user)

10 get :index

11 expect(assigns(:users)).to match_array [@user,user]

12 end

13 # :index テンプレートを表示すること

14 it "renders the :index template" do

15 get :index

16 expect(response).to render_template :index

17 end

18 end

19 # GET #new はアクセスを拒否すること

20 it "GET #new denies access" do

21 get :new

22 expect(response).to redirect_to root_url

23 end

24 # POST #create はアクセスを拒否すること

25 it "POST #create denies access" do

26 post :create, user: attributes_for(:user)

27 expect(response).to redirect_to root_url

28 end

29 end

spec/controllers/users_controller_spec.rb

Page 18: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

ロール Index Show Create Update Destroy

管理者 ○ ○ ○ ○ ○編集者 ○ ○ ○ ○ ○作者 ○ ○ ○ ○ ×

メンバー ○ ○ × × ×

ゲスト ○ × × × ×

ロールの実装やテストの際は、こういう表を作ると便利!

Page 19: RSpecによるRailsテスト入門 第六章 高度なコントローラスペック

thanx!● sexy muscle | Flickr - Photo Sharing!

https://www.flickr.com/photos/babagozum/3928521527/● Thinking | Flickr - Photo Sharing!

https://www.flickr.com/photos/aigle_dore/7914619060/● Spring babies are out! (84/365) | Flickr - Photo Sharing!

https://www.flickr.com/photos/chungholeung/8719051968/