LoginSignup
7
3

More than 5 years have passed since last update.

Railsのテスト環境でcookieを使う時の工夫

Last updated at Posted at 2018-01-19

Railsのテスト環境において暗号化cookieを使うとちょっとしたエラーが出る。

こんなの
NoMethodError: undefined method `signed' for #<Rack::Test::CookieJar:0x0000000XXXXXXXX>

これは、テスト環境においてRailsが使用しているライブラリが本番環境(および開発環境)のそれと違うために起きる問題...らしい

Railsチュートリアル内の「テスト内ではcookiesメソッドにシンボルを使用できない」という問題
↑参考にさせていただきました記事

暗号化(signed)と同様に、永続化(permanent)cookieも使えない。
このままではテストができないため、なんとかする。


まずは、cookieを一元的に管理する関数をApplicationHelperで定義する。

app/helpers/application_helper.rb
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モジュールを上書きする。

test/test_helper.rb
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のコードに誤りがあったため修正しました。

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