1. ホーム
  2. ruby-on-rails-3

[解決済み] リクエスト仕様における認証のスタブ化

2023-05-01 19:12:35

質問

リクエスト仕様を書くとき、セッションやスタブコントローラメソッドをどのように設定するのでしょうか? 私は統合テストで認証をスタブ化しようとしています - rspec/requests

以下はテストの例です。

require File.dirname(__FILE__) + '/../spec_helper'
require File.dirname(__FILE__) + '/authentication_helpers'


describe "Messages" do
  include AuthenticationHelpers

  describe "GET admin/messages" do
    before(:each) do
      @current_user = Factory :super_admin
      login(@current_user)
    end

    it "displays received messages" do
      sender = Factory :jonas
      direct_message = Message.new(:sender_id => sender.id, :subject => "Message system.", :content => "content", :receiver_ids => [@current_user.id])
      direct_message.save
      get admin_messages_path
      response.body.should include(direct_message.subject) 
    end
  end
end

ヘルパーです。

module AuthenticationHelpers
  def login(user)
    session[:user_id] = user.id # session is nil
    #controller.stub!(:current_user).and_return(user) # controller is nil
  end
end

そして、認証を処理するApplicationControllerです。

class ApplicationController < ActionController::Base
  protect_from_forgery

  helper_method :current_user
  helper_method :logged_in?

  protected

  def current_user  
    @current_user ||= User.find(session[:user_id]) if session[:user_id]  
  end

  def logged_in?
    !current_user.nil?
  end
end

なぜこれらのリソースにアクセスできないのでしょうか?

1) Messages GET admin/messages displays received messages
     Failure/Error: login(@current_user)
     NoMethodError:
       undefined method `session' for nil:NilClass
     # ./spec/requests/authentication_helpers.rb:3:in `login'
     # ./spec/requests/message_spec.rb:15:in `block (3 levels) in <top (required)>'

どのように解決するのですか?

リクエスト仕様とは ActionDispatch::IntegrationTest の薄いラッパーで、コントローラの仕様 (コントローラの仕様は ActionController::TestCase ). セッションメソッドが用意されていても、それがサポートされているとは思えません(つまり、他のユーティリティのためにインクルードされるモジュールもそのメソッドを含んでいるので、そこにあるのでしょう)。

ユーザー認証に使うどんなアクションでも、投稿でログインすることをお勧めします。すべてのUserファクトリーのパスワードを'password'(例)にすれば、次のようなことができます。

def login(user)
  post login_path, :login => user.login, :password => 'パスワード'.
終了