前提
表を作成するアプリをRailsを使って作成しています。
作成した表は、作成者のみが閲覧・編集・削除できるようにしたいと思っています。
やりたいこと
createアクションに関するリクエストスペックを書く。
書いたコード
spec/requests/tables_controller_spec.rb
describe"#create"do
context "as an authorized user" do
before do
@user = FactoryBot.create(:user)
end
it "adds a table" do
table_params = FactoryBot.attributes_for(:table)
sign_in @user
expect {
post tables_path, params: { table: table_params }
}.to change(@user.tables, :count).by(1)
end
end
end
spec/factories/users.rb
FactoryBot.define do
factory :user do
id {"1"}
email { "itirou@example.com" }
password { "itirou" }
end
end
spec/factories/tables.rb
FactoryBot.define do
factory :table do
id {"1"}
title { "表1" }
end
end
app/controllers/tables_controller.rb
class TablesController < ApplicationController
def create
@table = Table.new(table_params)
if @table.save
flash[:notice] = "表を新規登録しました"
redirect_to :tables
else
render "new"
end
end
def table_params
params.require(:table).permit(:title, :user_id)
end
end
テスト失敗
この状態で bundle exec rspec を行ってもテストは失敗します。
Failures:
1) Tables #create as an authorized user adds a table
Failure/Error:
expect {
post tables_path, params: { table: table_params }
}.to change(@user.tables, :count).by(1)
expected `Table::ActiveRecord_Associations_CollectionProxy#count` to have changed by 1, but was changed by 0
原因
user_idを登録できていないからです。
私が作成中のアプリでは、ビューに <%= f.hidden_field :user_id, value: current_user.id %> を書き込むことで、作成した表に作成者のuser_idを登録していました。
この方法では、上記のコードでテストできません。
解決
以下のように、コントローラのコードを書き換えることでテストが通ります。
app/controllers/tables_controller.rb
def create
@table = current_user.tables.new(table_params) #この行を変更
if @table.save
flash[:notice] = "表を新規登録しました"
redirect_to :tables
else
render "new"
end
end
def table_params
params.require(:table).permit(:title) #この行も変更
end
ビューに書いた <%= f.hidden_field :user_id, value: current_user.id %> も削除します。
所感
機能の実装のために書いたコードとテストは連動してないと意味がないと痛感しました。