解決したいこと
rspecでcreateアクションのテストを記述しているのですが、上手く行かず、countが増えません
発生している問題・エラー
Failures: 1) GogakusController#create as an authenticated user adds a project Failure/Error: expect { post :create, params: { gogaku: t_gogaku_params ,dictum_user: @dictum_user} }.to change(@dictum_user.gogakus,:count).by(1) expected `Gogaku::ActiveRecord_Associations_CollectionProxy#count` to have changed by 1, but was changed by 0 # ./spec/controllers/gogakus_controller_spec.rb:43:in `block (4 levels) in <main>' Finished in 0.64113 seconds (files took 1.35 seconds to load) 10 examples, 1 failure Failed examples: rspec ./spec/controllers/gogakus_controller_spec.rb:37 # GogakusController#create as an authenticated user adds a project
spec/controllers/gogakus_controller_spec.rb
require 'rails_helper' RSpec.describe GogakusController, type: :controller do describe "#show" do context "as an authorized user" do before do @dictum_user = FactoryBot.create(:dictum_user) @gogaku = FactoryBot.create(:gogaku, dictum_user: @dictum_user) end it "responds successfully" do log_in @dictum_user get :show, params: {id: @gogaku.id} # correct_user_g expect(response).to be_successful # expect(DictumUser).to receive(:find).with(@gogaku.id).and_return (@gogaku) end end context "as an unauthorized user" do before do @dictum_user = FactoryBot.create(:dictum_user) other_user = FactoryBot.create(:dictum_user) @gogaku = FactoryBot.create(:gogaku, dictum_user: other_user) end it "redirect to the root_url" do log_in @dictum_user get :show, params: { id: @gogaku.id } expect(response).to redirect_to root_url end end end ////// ここのcreateでエラー。showはエラーなし。 describe "#create" do context "as an authenticated user" do before do @dictum_user = FactoryBot.create(:dictum_user) end it "adds a project" do expect(@dictum_user.gogakus.count).to eq 0 t_gogaku_params = FactoryBot.attributes_for(:gogaku) log_in @dictum_user current_user expect(@dictum_user.gogakus.count).to eq 0 expect { post :create, params: { gogaku: t_gogaku_params ,dictum_user: @dictum_user} }.to change(@dictum_user.gogakus,:count).by(1) # expect(response).to redirect_to new_gogaku_path expect(@dictum_user.gogakus.count).to eq 1 end end end end
app/controllers/gogakus_controller.rb
class GogakusController < ApplicationController before_action :logged_in_user before_action :correct_user_g, only: [:show, :edit, :update, :destroy] def show render :layout => 'g_show' end def new @gogaku = Gogaku.new end def create @gogaku = current_user.gogakus.build(gogaku_params) if @gogaku.save flash[:success] = "登録完了!" redirect_to root_url else @feed_items = current_user.feed.paginate(page: params[:page]) flash[:danger] = @gogaku.errors.full_messages if @gogaku.errors.any? redirect_to new_gogaku_path end end def edit # @gogaku = Gogaku.find(params[:id]) end def update # @gogaku = Gogaku.find(params[:id]) gogaku_params = params.require(:gogaku).permit(:subject, :body, :file, :answer) if @gogaku.update(gogaku_params) flash[:notice]="更新成功" # @feed_items = current_user.feed.paginate(page: params[:page]) redirect_to root_url else flash[:danger] = @gogaku.errors.full_messages if @gogaku.errors.any? redirect_to controller: :gogakus,action: :edit, id: @gogaku.id end end def destroy # @gogaku = Gogaku.find(params[:id]) @gogaku.destroy flash[:notice]="削除しました" redirect_to request.referrer || root_url end private def gogaku_params params.require(:gogaku).permit(:subject, :body, :file, :answer,) end def correct_user_g @gogaku = current_user.gogakus.find_by(id: params[:id]) redirect_to root_url if @gogaku.nil? end end
spec/factories/dictum_users.rb
FactoryBot.define do factory :dictum_user do sequence(:name) { |n| "user#{n}" } sequence(:email) { |n| "test#{n}@example.com" } password { "password" } password_confirmation { "password" } end end
spec/factories/gogakus.rb
FactoryBot.define do factory :gogaku do subject {"English"} body {"in trip"} after(:build) do |gogaku| image_file = File.open("./spec/fixtures/files/Night_Sea.mp3") gogaku.file.attach(io: image_file,filename: "Night_Sea.mp3",content_type: 'audio/mp3') image_file.rewind end answer {"none"} association :dictum_user end end
自分で試したこと
私の予想ですが、
expect { post :create, params: { gogaku: t_gogaku_params ,dictum_user: @dictum_user} }.to change(@dictum_user.gogakus,:count).by(1)
ここの記述に誤りがあると思われます。コントローラーを見ていただいてわかる通り、gogaku.saveに失敗した場合、new_gogaku_pathにredirectすることになっていますが、
expect(@dictum_user.gogakus.count).to eq 0 t_gogaku_params = FactoryBot.attributes_for(:gogaku) log_in @dictum_user current_user expect { post :create, params: { gogaku: t_gogaku_params ,dictum_user: @dictum_user} }.to change(@dictum_user.gogakus,:count).by(0) expect(response).to redirect_to new_gogaku_path
このように記述した場合、テストに成功してしまいました。showアクションは成功しているので、postリクエストを送る処理の部分でミスがあると考えています。
・環境構築はDockerで行い、Ruby3.0.3 Rails6.1.5を使用しています。
・何かしらアドバイスがあればよろしくお願いいたします。

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。