LoginSignup
2
3

More than 3 years have passed since last update.

Railsアプリのテスト実行中に cookies.signed がエラー(undefined) になったときの対処法

Last updated at Posted at 2020-04-05

こんにちは、ペーパーエンジニアのよしこです。

Ruby on Railsのテストで、Cookies周りのバグに対応しました。
RSpecテスト環境での日本語情報が少なかったので、私と同じ初心者向けに情報共有します。

バグの内容

ControllerやHelperなどで使われているcookies.signed[:foo]をテストで呼び出すと、
NoMethodError: undefined method `signed' for #<Rack::Test::CookieJar:0x0>とエラーになりました。

cokkies.permanentcookies.encrypted でも同様のエラーになります。

hoges_controller.rb
class hogesController < ApplicationController
  def hogehoge
    pp cookies.signed[:foo] = "bar"
  end
end

上のコントローラー(もしくはヘルパー)のRSpecテストを書きます。

hoges_request_spec.rb
RSpec.describe "Hoges", type: :request do
  it { expect(hogehoge).to eq "bar" }
end

実行結果は、エラーとなります。

#ターミナル
$ rspec

Failures:

  1) Hoges #hogehoge
     Failure/Error: pp cookies.signed[:foo] = "bar"

     NoMethodError:
       undefined method `signed' for #<Rack::Test::CookieJar:0x00007ffddefd5460>
     # ./app/helpers/hoges_controller.rb:3:in 

対処方法(結論)

Rack::Test::CookieJarの未定義メソッド (undefined method) を定義し直します。

./spec/support/cookies.rbというファイル(名前は任意)を作成し、下のコードで保存します。

cookies.rb
# RSpecでcookies.signedがエラーになる対処
class Rack::Test::CookieJar
  def signed
    self
  end

  def permanent
    self
  end

  def encrypted
    self
  end
end

これで、 テストはパスできるはずです。

この解決方法は、GitHubのRSpec Issuesのコメントに記載されていました。
【GitHub】Signed cookies not available in controller specs - rspec-rails 3.5.0, rails 5.0 #1658
こちらの最下部コメントがヒントになりました。

@wangthony wangthony commented on 10 Nov 2018

@ivko999 's solution worked for me - thanks!
Even cleaner, just put it in a spec/support file:

# spec/support/cookies.rb
class ActionDispatch::Cookies::CookieJar
 def encrypted; self; end
 def signed; self; end
 def permanent; self; end # I needed this, too
end

なぜ動かないのか

Railsのcookieクラスは、環境によって参照元が変わります。

# テスト環境以外
ActionDispatch::Cookies::CookieJar

# テスト環境
Rack::Test::CookieJar

テスト環境のRack::Test::CookieJarが、
signed permanent encrypted メソッドをサポートしていないので、
テスト実行時にエラーになってしまいます。

※ ActionController::TestCaseではサポートしているとのことなので、Controllerテストではサポートしているのかもしれません。
【GitHub】Signed cookies not available in controller tests #27145

参考にしたブログ記事
Railsのインテグレーションテストでcookies.signedを使いたい

以上となります。
少しでもお力になれれば幸いです。

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