LoginSignup
11
5

More than 5 years have passed since last update.

rspecでcreateアクションのテスト

Posted at

問題

createアクションでメッセージを保存した時に、データベースのレコードが一つ増えているかどうかを検証するテストでNo route mathesエラーが出る。

コード

messagesコントローラー

messages_controller.rb
  def create
    @message = Message.new(create_params)
    if @message.save
      redirect_to group_messages_path(@group)
    else
      @groups = current_user.groups.includes(:users)
      @messages = Message.where(group_id: params[:group_id]).order(created_at: :ASC).includes(:user)
      flash.now[:alert] = "メッセージが送信できませんでした。"
      render action: :index
    end
  end

最初のコード

messsages_controller_spec.rb

〜略〜
it "データベースに新しいメッセージが登録されること" do
  expect{
    post :create, message: attributes_for(:message, group_id: group.id )
  }.to change(Message, :count).by(1)
end
〜略〜

これでテストしてみると以下のようなエラー文が!
(messageモデルはテキスト本文であるbodyというカラムがあり、FactoryGirlで定義しています)

Failures:

  1) MessagesController POST #create メッセージの保存に成功した場合 データベースに新しいメッセージが登録されること
     Failure/Error: post :create, message: attributes_for(:message, group_id: group.id )

     ActionController::UrlGenerationError:
       No route matches {:action=>"create", :controller=>"messages", :message=>{:body=>"Hello", :group_id=>81}}
     # ./spec/controllers/messages_controller_spec.rb:34:in `block (5 levels) in <top (required)>'
     # ./spec/controllers/messages_controller_spec.rb:33:in `block (4 levels) in <top (required)>'

Finished in 0.81058 seconds (files took 3.76 seconds to load)
4 examples, 1 failure

Failed examples:

rspec ./spec/controllers/messages_controller_spec.rb:32 # MessagesController POST #create メッセージの保存に成功した場合 データベースに新しいメッセージが登録されること

routeがいかれていると…。

binding.pryでparamsを確認してみると。

[1] pry(#<MessagesController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"sQeDsqZbUxrIrnHiW82gSPb3rOAqvgyrDdM2DdGdI2nWrIMCAyYS5+ZEi0vhFrBV1nLBQJFNBp6WwwhsMrbdxw==", "message"=>{"body"=>"あら"}, "commit"=>"Send", "controller"=>"messages", "action"=>"create", "group_id"=>"1"} permitted: false>

思ったよりbodyが深く埋め込まれてました。

つまり、今現在のテストでは、
params: {:action=>"create", :controller=>"messages", :message=>{:body=>"Hello", :group_id=>81}}

こんなハッシュになっているところを

params: {:action=>"create", :controller=>"messages", :message=>{:body=>"Hello"}, :group_id=>81}

というふうにすればrouteがいい感じになるのではという仮説のもと、いろいろ試行錯誤してみたところ、以下のコードでテストをパスしました。

messsages_controller_spec.rb
it "データベースに新しいメッセージが登録されること" do
  expect{
    post :create, params: { message: attributes_for(:message, { body: 'hello' }), group_id: group.id }
  }.to change(Message, :count).by(1)
end

it内ではなくて、messageのFactorygirlで定義しようとも思ったのですが、うまくできませんでしたね。

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5