同じような前提条件と検証内容で冗長になって来たので、リファクタリングとして共通化しました。
contextに記載した内容を実現する実装部分(前提条件)は、include_contextで呼び出して、shared_contextで受け、itの部分(検証内容)は、it_behaves_likeで呼び出して、shared_examples_forで受ければ共通化できて幸せ(可読性アップ)になれる。
リファクタリング
例えば、view specでログイン有無とサブドメインか否かで前提条件が別れる場合、それぞれをshared_contextで定義して、include_contextで呼び出してあげる。
また、サブドメインの検証内容をshared_examples_for(複数検証できる)で定義して、it_behaves_likeで呼び出してあげる。
すると、ログイン状態やサブドメインのデータ作成、サブドメインの検証内容を複数回書かなくてよくなる。
require 'rails_helper' RSpec.describe 'layouts/application', type: :view do let!(:user) { FactoryBot.create(:user) } + shared_context 'login' do + before { login_user user } + end + + shared_context 'subdomain' do+ before do + @use_space = FactoryBot.create(:space) + end+ # こっちの方がシンプルですね。 + before { @use_space = FactoryBot.create(:space) } + end <省略> + shared_examples_for 'サブドメイン' do + it 'スペース名が含まれる' do + render+ expect(rendered).to match(Regexp.escape(@use_space.name))+ # こっちの方がシンプルですね。 + expect(rendered).to include(@use_space.name) + end + it 'スペース編集のパスが含まれる' do + render+ expect(rendered).to match("\"#{Regexp.escape(edit_space_path(@use_space))}\"")+ expect(rendered).to include("\"#{edit_space_path(@use_space)}\"") + end + end - context '未ログイン、サブドメイン' do + context '未ログイン' do + include_context 'subdomain' - before do - @use_space = FactoryBot.create(:space) - end + it_behaves_like 'サブドメイン' - it 'スペース名が含まれる' do - render - expect(rendered).to match(Regexp.escape(@use_space.name)) - end - it 'スペース編集のパスが含まれる' do - render - expect(rendered).to match("\"#{Regexp.escape(edit_space_path(@use_space))}\"") - end end - context 'ログイン中、サブドメイン' do + context 'ログイン中' do + include_context 'login' + include_context 'subdomain' - before do - login_user user - @use_space = FactoryBot.create(:space) - end + it_behaves_like 'サブドメイン' - it 'スペース名が含まれる' do - render - expect(rendered).to match(Regexp.escape(@use_space.name)) - end - it 'スペース編集のパスが含まれる' do - render - expect(rendered).to match("\"#{Regexp.escape(edit_space_path(@use_space))}\"") - end end end
shared_examples_for(←it_behaves_like)は、rspecでエラーになった時に出力されるので、contextの内容から外した方がきれい。
【参考】ここまでのコミット内容
https://dev.azure.com/nightonly/rails-app-origin/_git/rails-app-origin/commit/64ac977ab7c658e39a805bb5aba1cc92ec40d33a