LoginSignup
5

More than 5 years have passed since last update.

Rails 4系と5系で互換性のあるcontroller specを書く方法

Posted at

環境

  • 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

spec/support/util/params_wrapper.rb
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
spec/rails_helper.rb
Dir["#{__dir__}/support/**/*.rb"].each { |f| require f }

RSpec.configure do |config|
  config.include ParamsWrapper
end

controller specでは下記のように呼び出します。

spec/controllers/users_spec.rb
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 を使っていなかったので特に考慮していなかった)


  1. このサンプルではParamsWrapperをincludeしていますが、rails_helper.rbにメソッドを直接定義するのでもいいです 

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
5