Railsのテスト環境において暗号化cookieを使うとちょっとしたエラーが出る。
NoMethodError: undefined method `signed' for #<Rack::Test::CookieJar:0x0000000XXXXXXXX>
これは、テスト環境においてRailsが使用しているライブラリが本番環境(および開発環境)のそれと違うために起きる問題...らしい
Railsチュートリアル内の「テスト内ではcookiesメソッドにシンボルを使用できない」という問題
↑参考にさせていただきました記事
暗号化(signed)と同様に、永続化(permanent)cookieも使えない。
このままではテストができないため、なんとかする。
まずは、cookieを一元的に管理する関数をApplicationHelperで定義する。
module ApplicationHelper
...
#cookie取得
def getcookie(tag)
cookies.signed[tag]
end
#cookie保存
def setcookie(tag, value)
cookies.permanent.signed[tag] = value
end
#cookie削除
def deletecookie(tag)
cookies.delete(tag)
end
end
そして、ソースコードからcookieを呼び出す時は、必ずこの関数を使って呼び出すようにする。
続いて、テスト環境でのみ、この関数をpermanentやsignedを使わないものに書き換える。
test_helper.rbというファイルにおいて、テスト環境でのみ使用する関数を定義することが出来る。ここで前述のApplicationHelperモジュールを上書きする。
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
fixtures :all
...
module ApplicationHelperFixes
#テスト用に再定義を行う
#cookie取得
def getcookie(tag)
cookies[tag.to_s] #signed使わない
end
#cookie保存
def setcookie(tag, value)
cookies[tag.to_s] = value #signed,permanent使わない
end
#cookie削除
def deletecookie(tag)
cookies.delete(tag.to_s) #これはとくに変わりなし
end
end
#変更を適用する
ApplicationHelper.send :prepend, ApplicationHelperFixes
end
これでテストを実行すると、こちらの関数が適用されるために前述のエラーは出なくなった。
Rubyのオープンクラスの凄さを思い知った。
これが正しいテストヘルパーの使い方なのかとか、他の解決方法とか、弊害とかまったくわからないけど、とりあえず解決したので投稿させていただきました。
何か間違いがあれば暖かく教えていただけると幸いです。
追記:2018/1/20 一部test_helperのコードに誤りがあったため修正しました。