Rails6で、controllerのgenerateするとspec/controller/xxx_controller_spec.rbが作られる。
scaffoldすると、spec/requests/xxx_spec.rbが作られるが、controllerのは作られない。
どっち使うべきか迷ったが、Rails5からrequest spec推奨になってたみたい。
controllerがないのにcontroller specに書くのは変なので、request spec使うべき。
同じ事が出来るので、request spec推奨という流れなのかと。
request specに書き換える
spec/controllers/top_controller_spec.rbを削除
require 'rails_helper' RSpec.describe TopController, type: :controller do let!(:user) { create(:user) } describe 'GET #index' do context '未ログイン' do it 'returns a success response' do get :index expect(response).to be_successful end it 'use index template' do get :index should render_template('index') end end context 'ログイン中' do before do login_user user end it 'returns a success response' do get :index expect(response).to be_successful end it 'use index template' do get :index should render_template('index') end end end end
spec/requests/top_spec.rbを作成
require 'rails_helper' RSpec.describe 'Top', type: :request do let!(:user) { create(:user) } describe 'GET #index' do context '未ログイン' do it 'renders a successful response' do get root_path expect(response).to be_successful end it 'use index template' do get root_path should render_template('index') end end context 'ログイン中' do before do sign_in user end it 'renders a successful response' do get root_path expect(response).to be_successful end it 'use index template' do get root_path should render_template('index') end end end end
spec/rails_helper.rbの下記を削除
config.include Devise::Test::ControllerHelpers, type: :controller config.include ControllerMacros, type: :controller
最終的に下記が残った
# Use devise config.include Devise::Test::IntegrationHelpers, type: :request config.include Devise::Test::ControllerHelpers, type: :view config.include ControllerMacros, type: :view config.include FactoryBot::Syntax::Methods
【参考】ここまでのコミット内容
https://dev.azure.com/nightonly/rails-app-origin/_git/rails-app-origin/commit/1f6c4f1da631d7701f2b983a4028bfae145e2c96
下記はそのま流用
ControllerMacrosって気持ち悪いけど、Devise::Test::ControllerHelpersに合わせてそのままに。
view specでrequest specと同様にすると、user_signed_in?がないと怒られるので残す事にしました。
spec/rails_helper.rb
# Use devise require 'devise'
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
spec/support/controller_macros.rb
module ControllerMacros def login_user(user) allow(controller).to receive(:authenticate_user!).and_return(true) @request.env['devise.mapping'] = Devise.mappings[:user] sign_in user end end
spec/factories/users.rb
FactoryBot.define do factory :user do pass = Faker::Internet.password(min_length: 8) email { Faker::Internet.email } password { pass } password_confirmation { pass } end end
“Rails5からrequest spec推奨になってた” に対して1件のコメントがあります。