6
2

More than 1 year has passed since last update.

RSpecのbefore_actionのテストrequest specで書く

Posted at

TL;DR

mock class(Controller)を作成して、routingを追加して作成する

なぜrequest specでbefore_action を書くことになったのか

抽象化しているまたは、ApplicationControllerで全てに
適応する、メゾッドのテストを記載しないといけなくなり、controller specは使えず(anonymous controllerは利用できないため)対応を考えた。

想定しているcontroller

application_controller.rb
class ApplicationController < ActionController::Base
   before_action :authenticate

   def authenticate
       // headerからauth処理関係
   end
end

上記の問題は(実装もあるがテストで)、ApplicationController をrouting実装されておらず、request specでテストが記述しづらい。

ので、stack overflow
をもとにMockControllerを実装した

application_controller_spec.rb
describe 'Host header attack defense', type: :request do
  before do
    mock_controller = Class.new(ApplicationController) do
      def index
        render json: { ok: true }
      end
    end
    stub_const('MockController', mock_controller)

    Rails.application.routes.disable_clear_and_finalize = true
    Rails.application.routes.draw do
      get '/mock', to: 'mock#index'
    end
  end

  after { Rails.application.reload_routes! }

  context '#authenticate' do
    let(:headers) { { "Content-Type": "application/json" } }
    subject {  get '/mock', headers: headers }
    it { is_expect.to eq 200 }
    // 他にわしゃわしゃ
  end
end

個人的には結構、汎用性高くて好みです。(test onlyのroutingを記述しなくて済む)。
抽象化した場合(Concerns使ってもええんやで)、ApplicationControllerや継承元となるControllerのテストを書く時楽ちんですが、これ重くなるんじゃない?とも思ってる。

他に書き方あったら教えてください。

6
2
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
6
2