Anonymous Controller を使ってコントローラのテストを RSpec で記述する

ApplicationController に以下のような認証用のメソッドを定義する事は、よくあると思います。

# coding: utf-8
class ApplicationController < ActionController::Base
# 略
  def current_user
    # ログイン中のユーザオブジェクトを返す
  end

  def logged_in?
    # ログイン状態を返す
  end
# 略
end

こうした機能のテストはどう行えばいいのか悩んでいましたが AnonymousController を利用するとうまく書けるようです。

# coding: utf-8
require 'spec_helper'

describe ApplicationController, "認証" do
  controller do
    def index
      @user = User.create!(:login => "hoge") # ユーザ情報は適当に入力、スタブを用いてもいいかも。
      session[:user_id] = params[:logged_in] ? @user.id : nil
      render :text => logged_in? ? current_user.login : "not logged in."
    end
  end

  it "ログイン中のユーザが見つかる" do
    get :index, :logged_in => true
    user = User.find_by_login("hoge")
    session[:user_id].should == user.id
    response.body.should == user.login
  end

  it "ログインしていない" do
    get :index, :logged_in => false
    session[:user_id].should == nil
    response.body.should == "not logged in."
  end
end

このように、検証用に使うコントローラをその場で定義して、そのメソッドを呼び出す事でテストを行えます。上のコードで行っているように任意のパラメータを渡す事もできるので、うまく使えば色々なテストに応用できそうです。

正直 RSpec に関しては勉強不足が否めないので、もっとスマートな方法があればぜひご教示お願いします。

参考:http://relishapp.com/rspec/rspec-rails/v/2-6-rc/dir/controller-specs/anonymous-controller