Ruby on Railsでcookie情報の変更を考慮したテストを書いてみた
この記事はVOYAGE GROUP エンジニアブログ : Advent Calendar 2014の15日目の記事になります。
こんにちは。@nissy0409240です。
VOYAGE GROUPで新卒一年目のエンジニアとして、毎日楽しくお仕事しています!!
寒くてやる気が出ない日々が続きますが、毎日のタスクや、音ゲー部の活動を疎かにすることなく、
同期の無茶ぶりに応えていこうと思いました。
しかし、本エントリーではRuby on Railsでcookie情報の変更を考慮したテストを書く時に使った
gemをご紹介したいと思います。
「同期で一番面白いエンジニア」という一文にそぐわない記事を執筆していることを心よりお詫び申し上げます。
— Nissy (@nissy0409240) December 15, 2014
準備
まず、新しいRailsプロジェクトを下記コマンドで生成します。
$ ./bin/rails new show_me_the_cookie_test -T
今回はRSpecを使ったテストを書きたいので、-Tオプションを付けて実行します。
続いて、scaffoldでさくっとCRUD機能がついた雛形を作成します。
$ ./bin/rails g scaffold task content:text
最後に、DBの作成と生成されたマイグレーションの適用を行います。
$ ./bin/rake db:create $ ./bin/rake db:migrate
以上のコマンドを行うことで、簡単なアプリケーションが作成されます。
なお、上記コマンドはこちらの書籍を参考とさせて頂きました。パーフェクトRuby on Rails:書籍案内|技術評論社
show_me_the_cookies
ここで、今回使うgemをご紹介します。nruth/show_me_the_cookies · GitHub
こちらのgemはe2eテストを書く時に用いられることが多いcapybaraというgemが無いと使えません。
そのため、capybaraのインストールも必要です。
show_me_the_cookiesのインストール方法はGemfileに下記一文を追加した後にbundle installを実行すればOKです。
gem 'show_me_the_cookies'
また、spec/rails_helper.rbに
config.include ShowMeTheCookies, :type => :feature
の一文を追記することも忘れずに行いましょう。
作成
ここからは実際に作って行こうと思います。
まず、ログイン機能の仮実装を行います。
仮実装が完了したらcookie情報の変更を考慮したテストを書いて行きます。
しかし、README.mdにcookieの作り方が書いてなかったので、ソースコードを見てみます。
すると
def create_cookie(name, value, options = {}) current_driver_adapter.create_cookie(name, value, options) end
というメソッドを見つけました。
こちらを参考に
require 'rails_helper' feature "Tasks", :type => :feature do it '非ログイン状態でアクセスすると、ログインページへリダイレクトしていること' do visit tasks_path expect(current_url).to eq login_url end it 'cookieが存在する場合タスク一覧画面を表示すること' do create_cookie('sso', 'hogehogehoge') puts show_me_the_cookie('sso') visit tasks_path expect(current_url).to eq tasks_url end end
というテストを書いてみます。
puts文は実際に'sso'というキーcookieが返って来るのかを確認するために、
show_me_the_cookieメソッドの結果を出力するようにしています。
このテストを実行してみると
二行目にssoというキーのcookieが生成されていることが確認出来ました。
これでcookie情報の変更を考慮したテストすることが出来そうです。
それでは、ここまでの内容を踏まえて下記の様にソースコードを
class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception private def login_required sso_key = cookies[:sso] unless sso_key redirect_to login_path and return end unless valid_sso_key?(sso_key) redirect_to login_path and return end end def valid_sso_key?(sso_key) true end def current_user nil end end
また、下記の様にテストコードを実装します。
require 'rails_helper' feature "Tasks", :type => :feature do it '非ログイン状態でアクセスすると、ログインページへリダイレクトしていること' do visit tasks_path expect(current_url).to eq login_url end it 'cookieが存在する場合タスク一覧画面を表示すること' do create_cookie('sso', 'hogehogehoge') visit tasks_path expect(current_url).to eq tasks_url end end
最後に、仮実装のコードから
def login_required if current_user.nil? redirect_to login_path and return end end
こちらのコードを削除します。
以上を踏まえ、テストを実行すると
こちらのようにテストが通り、無事、cookie生成時とそうでない場合のテストを書くことが出来ました。
まとめ
今回、Ruby on Railsでcookie情報の変更を考慮したテストを書くにあたり学んだ知見をまとめさせて頂きました。
つたない実装ではございますが、このエントリーの内容を実装したものがこちらになります。Nissy0409/show_me_the_cookie_test · GitHub
最後までお付き合い頂き、ありがとうございました。
明日はジバニャン方程式で有名な@Akiyahさんです。
お楽しみに!!