💡
この記事は Middleman 時代に書いた古いものです。記録のため、astro-notion-blog に移行していますが、あまり参考にしないでください。
request spec のテンプレート作成
kurasus_controller.rb に対して,一通りの request spec が作成できたので,これをベースに template を作成する.
-
kurasus_spec.rb を lib/templates/rspec/integration/request_spec.rb にコピーする.
cp spec/requests/kurasus_spec.rb lib/templates/rspec/integration/request_spec.rb
-
クラス名などを erb を使って書き換える.最終的に生成した request_spec.rb を掲載しておく.とりあえず現状のもので今後修正する可能性はある.
require 'rails_helper' RSpec.describe :<%= class_name.pluralize %>, type: :request do include Devise::Test::IntegrationHelpers let(:return_path) { <%= plural_table_name %>_path(edit_mode: true) } context 'login by hkob' do let!(:object) { <%= singular_table_name %>_factory :factory_one } let!(:others) { <%= singular_table_name %>_factory :factory_other } let(:not_mine) { <%= singular_table_name %>_factory :factory_not_mine } teacher_login :hkob describe 'GET #index' do context 'normal mode' do subject { -> { get <%= plural_table_name %>_path } } it_behaves_like :response_status_check, 200 it_behaves_like :response_body_includes, %w[XXX一覧: 表示される文字列] it_behaves_like :response_body_not_includes, '表示されない文字列' end context 'edit mode' do subject { -> { get <%= plural_table_name %>_path(edit_mode: true) } } it_behaves_like :response_status_check, 200 it_behaves_like :response_body_includes, %w[XXX一覧: 表示される文字列] end end describe 'GET #new' do subject { -> { get new_<%= singular_table_name %>_path } } it_behaves_like :response_status_check, 200 end describe 'POST #create' do before { @attrs = object.attributes; object.destroy } subject { -> { post <%= plural_table_name %>_path, params: {<%= singular_table_name %>: @attrs}} } context '正しいパラメータに対して' do it_behaves_like :response_status_check, 302 it_behaves_like :increment_object_by_create, <%= class_name %> it_behaves_like :redirect_to it_behaves_like :flash_notice_message, 'XXXを登録しました.' end context '不正なパラメータに対して' do before { @attrs['name'] = nil } it_behaves_like :response_status_check, 200 it_behaves_like :not_increment_object_by_create, <%= class_name %> it_behaves_like :flash_alert_message, 'XXXが登録できません.' end end describe 'GET #edit' do context 'owned object' do subject { -> { get edit_<%= singular_table_name %>_path(object) } } it_behaves_like :response_status_check, 200 it_behaves_like :response_body_includes, '2300' end context 'not owned object' do subject { -> { get edit_<%= singular_table_name %>_path(not_mine) } } it_behaves_like :response_status_check, 302 it_behaves_like :redirect_to it_behaves_like :flash_alert_message, 'XXXを編集する権限がありません.' end end describe 'PATCH #update' do before { @attrs = object.attributes } context 'owned object' do subject { -> { patch <%= singular_table_name %>_path(object), params: {<%= singular_table_name %>: @attrs} } } context '正しいパラメータに対して' do before { @attrs['name'] = 'new name' } it_behaves_like :response_status_check, 302 it_behaves_like :change_object_value_by_update, <%= class_name %>, :name, 'new name' it_behaves_like :redirect_to it_behaves_like :flash_notice_message, 'XXXを更新しました.' end context '不正なパラメータに対して' do before { @attrs['name'] = nil } it_behaves_like :response_status_check, 200 it_behaves_like :not_change_object_value_by_update, <%= class_name %>, :name it_behaves_like :flash_alert_message, 'XXXが更新できません.' end end context 'not owned object' do subject { -> { put <%= singular_table_name %>_path(not_mine), params: {<%= singular_table_name %>: @attrs} } } it_behaves_like :response_status_check, 302 it_behaves_like :redirect_to it_behaves_like :flash_alert_message, 'XXXが更新できません.' end end describe 'DELETE #destroy' do context 'owned object' do subject { -> { delete <%= singular_table_name %>_path(object), params: {<%= singular_table_name %>: @attrs} } } it_behaves_like :response_status_check, 302 it_behaves_like :decrement_object_by_destroy, <%= class_name %> it_behaves_like :redirect_to it_behaves_like :flash_notice_message, 'XXXを削除しました.' end context 'now owned object' do subject { -> { delete <%= singular_table_name %>_path(not_mine), params: {<%= singular_table_name %>: @attrs} } } it_behaves_like :response_status_check, 302 it_behaves_like :redirect_to it_behaves_like :flash_alert_message, 'XXXを削除する権限がありません.' end end describe 'GET #show' do context 'owned object' do subject { -> { get <%= singular_table_name %>_path(object) } } it_behaves_like :response_status_check, 200 it_behaves_like :response_body_includes, %w[XXX表示: YYY] end context 'now owned object' do subject { -> { get <%= singular_table_name %>_path(not_mine) } } it_behaves_like :response_status_check, 302 it_behaves_like :redirect_to it_behaves_like :flash_alert_message, 'XXXを表示する権限がありません.' end end end context 'not login' do describe 'GET #index' do subject { -> { get <%= plural_table_name %>_path } } it_behaves_like :response_status_check, 302 it_behaves_like :response_body_not_includes, %w[表示されない文字列] end end end
request spec のまとめ
request spec は以前の controller spec の代わりになるものである. controller spec と違って内部のオブジェクトまではテストせず,あくまでリクエストの成功などを確認するだけに限定された. このため,controller spec よりもテストがやりやすくなったと思う. 以下に今回の kurasus_spec.rb のテスト結果をまとめて示しておく.
Kurasus
login by hkob
GET #index
normal mode
behaves like response_status_check
response should be 200
behaves like response_body_includes
response body includes ["クラス一覧:", "小林弘幸", "2300"]
behaves like response_body_not_includes
response body does not include 5300
edit mode
behaves like response_status_check
response should be 200
behaves like response_body_includes
response body includes ["クラス一覧:", "小林弘幸", "2300", "5300"]
GET #new
behaves like response_status_check
response should be 200
POST #create
正しいパラメータに対して
behaves like response_status_check
response should be 302
behaves like increment_object_by_create
should change `Kurasu.count` by 1
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_notice_message should eq "クラスを登録しました."
不正なパラメータに対して
behaves like response_status_check
response should be 200
behaves like not_increment_object_by_create
should not change `Kurasu.count`
behaves like flash_alert_message
should eq "クラスが登録できません."
GET #edit
owned object
behaves like response_status_check
response should be 200
behaves like response_body_includes
response body includes 2300
not owned object
behaves like response_status_check
response should be 302
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_alert_message
should eq "クラスを編集する権限がありません."
PATCH #update
owned object
正しいパラメータに対して
behaves like response_status_check
response should be 302
behaves like change_object_value_by_update
should change `klass.find(object.id).send(key)` from "2300" to "new name"
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_notice_message
should eq "クラスを更新しました."
不正なパラメータに対して
behaves like response_status_check
response should be 200
behaves like not_change_object_value_by_update
should not change `klass.find(object.id).send(key)`
behaves like flash_alert_message
should eq "クラスが更新できません."
not owned object
behaves like response_status_check
response should be 302
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_alert_message
should eq "クラスが更新できません."
DELETE #destroy
owned object
behaves like response_status_check
response should be 302
behaves like decrement_object_by_destroy
should change `Kurasu.count` by -1
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_notice_message
should eq "クラスを削除しました."
now owned object
behaves like response_status_check
response should be 302
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_alert_message
should eq "クラスを削除する権限がありません."
GET #show
owned object
behaves like response_status_check
response should be 200
behaves like response_body_includes
response body includes ["クラス表示:", "2300", "(小林弘幸)"]
now owned object
behaves like response_status_check
response should be 302
behaves like redirect_to
should redirect to "/kurasus?edit_mode=true"
behaves like flash_alert_message
should eq "クラスを表示する権限がありません."
not login
GET #index
behaves like response_status_check
response should be 302
behaves like response_body_not_includes
response body does not include ["クラス一覧:", "小林弘幸", "2300", "5300"]
長くなったので今日はここまで