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件のコメントがあります。