LoginSignup
30
39

More than 5 years have passed since last update.

Controller spec基本 - parameterとルーティングエラーについて

Posted at

RSpec コントローラースペックを書いていて、ActionController::UrlGenerationError: No route matches みたいなエラーが発生した場合の回避方法。

はじめに

コントローラスペックの基本構文

例:

let(:params) { { contact: FactoryGirl.attributes_for(:contact) } }
post :create, params
  • HTTPメソッド(post)
  • コントローラメソッド(:create)
  • メソッドに渡すパラメータ(params) 任意

パラメータに関する注意点

rake routes で確認出来るpathに含まれるパラメータや、POST時のbodyに含まれるもの全てをメソッドに渡すパラメータ(params)にHashで渡す。

nested resourcesやconcernsでresourceをネストさせた場合は、親resource_idなども含まれる。

例:アクセスしたいControllerのroutesが

message_comments GET /messages/:message_id/comments(.:format) comments#index

みたいな感じだったら

let(:params) { { message_id: 101 } }
get :index, params

でアクセスできる。
pathに含まれるparameterが足りない場合、こんなエラーが発生する。

発生するエラー

ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"messages_controller"}

ネストしてるリソースの書き方例を細かめに。

nested resource テスト記載例

config/routes.rb

config/routes.rb
concern :commentable do
  resources :comments
end

resources :messages, concerns: :commentable
./bin/rake routes

生成されるroutes (commentable部分のみ)

    message_comments GET    /messages/:message_id/comments(.:format)          comments#index
                     POST   /messages/:message_id/comments(.:format)          comments#create
 new_message_comment GET    /messages/:message_id/comments/new(.:format)      comments#new
edit_message_comment GET    /messages/:message_id/comments/:id/edit(.:format) comments#edit
     message_comment GET    /messages/:message_id/comments/:id(.:format)      comments#show
                     PATCH  /messages/:message_id/comments/:id(.:format)      comments#update
                     PUT    /messages/:message_id/comments/:id(.:format)      comments#update
                     DELETE /messages/:message_id/comments/:id(.:format)      comments#destroy

こんなコントローラーを・・

app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  def new
  end

  def create
    # TODO : save
  end

  def update
    # TODO : save
  end

  # ... 省略

  private

  def comment_params
    params.require(:comment).permit(:content)
  end
end

RSpecでテスト・・・

specs/controllers/comments_controller_spec.rb
require 'rails_helper'

RSpec.describe CommentsController, type: :controller do
  describe "GET #new" do
    subject { get :new, params }
    let(:params) { { message_id: 100 } }
    it { is_expected.to be_success }
  end

  describe "POST #create" do
    subject { post :create, params }
    let(:params) do
      { 
        message_id: 100,
        comment: {
          content: 'Test message comment'
        }
      }
    end
    it { is_expected.to be_success }
  end

  describe "PATCH #update" do
    subject { patch :update, params }
    let(:params) do
      { 
        id: 1,
        message_id: 100,
        comment: {
          content: 'Test message comment'
        }
      }
    end
    it { is_expected.to be_success }
  end
end

参考

30
39
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
30
39