質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

1812閲覧

Rspecでcreateアクションのテストが上手く動作せず、countが増えない

senseIY

総合スコア281

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2022/03/24 02:52

解決したいこと

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を使用しています。
・何かしらアドバイスがあればよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

自己解決出来ました。どうやらファイルの読み込み方がcreateとrspecで異なる場合エラーになるようです
https://github.com/rails/rails/issues/41991
このサイトを参考にさせていただき、全く同じように記述しました。
前に調べた際にdockerのバグが原因でファイルを読み込めないのではないかという結論に達した時に、rspecだけファイルの読み込み方を変えていました。誰かの参考になれば幸いです。

投稿2022/03/24 10:24

senseIY

総合スコア281

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

おそらく validationにひかかってるんですね。
なにが問題なのか明らかにしましょう

いくつか方法はありますが
model Gogaku のcode見せてください。
if @gogaku.save! と ! をいれると原因が分かるかもしれません。
flash[:danger] を PP してみるというのもありかと。

投稿2022/03/24 10:01

winterboum

総合スコア23349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

senseIY

2022/03/24 10:31 編集

コメントありがとうございます。何とか自己解決出来ました。どうやらコントローラー部分とrspecの部分でファイルの読み込み方が異なっていたことが原因でエラーが出たようです。以前は ``` 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') end ``` このように読み込んでいました。なぜかというとちょうど自分の使っているバージョンと近い記事でDockerのバグが報告されていたからです。ですが、その時はリンクに貼ったモジュールの組み込み方が分からず、上のコードで代用していました。 お時間を割いていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問