環境
- Rails v5.0.0.1
- rspec-rails v3.5.1
前置き
Rails 4系以前と5系ではcontroller specの params
の渡し方が変わっています。
Rails 4系まで
get :show, { id: 1 }
Rails 5系
get :show, params: { id: 1 }
Rails 5系で古い書き方をすると下記のようなDEPRECATION WARNINGが出ます。
DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions.
Examples:
get :show, params: { id: 1 }, session: { user_id: 1 }
process :update, method: :post, params: { id: 1 }
普通のアプリならメッセージに従ってspecを書き直せばいいのですが、mountable engineのようにgemの中に含まれるspecの場合はそうはいきません。
specファイルになるべく差分を発生させず、Rails 4系と5系で両方で動くcontroller specを紹介します。
やり方
params_wrapper
というラッパを用意するだけです 1
module ParamsWrapper
def params_wrapper(params = {})
if Gem::Version.new(Rails.version) >= Gem::Version.new("5.0.0")
{ params: params }
else
params
end
end
end
Dir["#{__dir__}/support/**/*.rb"].each { |f| require f }
RSpec.configure do |config|
config.include ParamsWrapper
end
controller specでは下記のように呼び出します。
get :show, params_wrapper(id: 1)
これでRails 4系以前では get :show, { id: 1 }
が、Rails 5系以降では get :show, params: { id: 1 }
が実行されます。
params_wrapper
を挟むことでcontroller specの各所でRailsのバージョン分岐を書く必要がなくなってspecがシンプルになります。
実際にこの対応を行ったcommit
量が多いと書き換えは大変ですが、元のspecとそんなに差分もなく違和感なく読める(と思う)のがいいです。
備考: sessionについて
今回は params
だけだったのでこのような対応でしたが、 session
も考慮すると対応が若干面倒くさそうな予感がしています。(今回のcontroller specだと session
を使っていなかったので特に考慮していなかった)
-
このサンプルでは
ParamsWrapper
をincludeしていますが、rails_helper.rbにメソッドを直接定義するのでもいいです ↩