私がRailsを始めた頃は、rspecでのコントローラのテストをそのまま書くのが普通ですが、 最近だとコントローラのテストはリクエストスペックが主流のようです。
そんなことを気にしながらリクエストスペックの設定を進めていると「あれ、これリクエストの たびに、認証情報などのヘッダ書かないといけないのか?」と思って調べてみたところ、 ちょうど良い方法がわかったのでここにまとめておきます。
Request Specのデフォルトのヘッダーを定義する
ヘッダをデフォルトで設定するには、requst spec内で呼び出せる、 get, post, patch, put, deleteなどのメソッドをラップしてあげることでspecのファイルごとに毎回 ヘッダを付与する処理を書かなくて済むようにすることができます。
reqest specの各HTTPメソッドに対応したメソッドはそれぞれ第二引数でheaderを設定することができます。
get '/users/', params: params, header: header
なので、このheader部分にラップした関数でデフォルトのヘッダーを付与して楽しちゃおうというのが今回のやり方です。
Request Helper(HTTPメソッドのラッパ)を用意
まずspec/support配下に下記のようなファイルを用意します。
spec/support/request_spec_helper.rb
module RequestSpecHelper
%i[get post patch put delete head].each do |name|
define_method(name) do |path, params: {}, headers: {}|
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
end
end
define_methodを使ってメタプロしているのでちょっとわかりづらいですが、 実直に書いていくと下記のようになります。
module RequestSpecHelper
def get(path, params: {}, headers: {})
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
def post(path, params: {}, headers: {})
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
def patch(path, params: {}, headers: {})
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
def put(path, params: {}, headers: {})
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
def delete(path, params: {}, headers: {})
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
def head(path, params: {}, headers: {})
super(path, params: params&.to_json, headers: default_request_headers&.merge(headers))
end
end
ここでのsuperはもともとのActionDispatch::Integration::RequestHelpersクラスのそれぞれのメソッドをさしています。 コードをよく見るとそれぞれでdefault_request_headersという変数が呼ばれているかと思うのですが、 ここにletなどであらかじめデフォルトの引数を設定しておけばspecファイルの中では
post '/path/to/endpoint', params: params
という感じで、認証に使うようなヘッダなど毎回使うものを定義せずにspecを書くことができるようになります。
このファイルが用意できたらあとは、ファイルを読み込んであげれば良いので、 spec/rails_helper.rbに
RSpec.configure do |config|
~~~
config.include RequestSpecHelper, type: :request
~~~
end
という形でrequest specの時だけ同ファイルを読み込むようにしてあげると上のメソッドが使えるようになります。
かなり手短にすませましたが、controller specからrequest specに移行するのに必要と思われる手順なのでまとめておきました。