2012-09-18 50 views
1

我有一个SearchesController,需要用户登录才能完成任务。如何模拟登录进行控制器测试?

我想写一个rspec帮助函数login来模拟登录进行控制器测试。 (注意:我将分别处理集成/请求规范。)我的尝试没有成功:ApplicationController中的logged_in?方法返回false。

问题:如何编写'登录'助手?

这里的RSpec的控制器测试:

# file: spec/controllers/searches_controller_spec.rb 
require 'spec_helper' 
require 'controllers_helper' 
describe SearchesController do 
    include ControllersHelper 

    describe "GET index" do 

    it 'without login renders login page' do 
     get :index 
     response.should redirect_to(login_path) 
    end 

    it 'with login finds searches belonging to user' do 
     me = FactoryGirl.create(:user) 
     my_searches = FactoryGirl.create_list(:search, 2, :user => me) 
     not_me = FactoryGirl.create(:user) 
     not_my_searches = FactoryGirl.create_list(:search, 2, :user => not_me) 

     login(me) # want to define this in spec/controllers_helper.rb 
     get :index 
     assigns(:searches).should =~ my_searches 
    end 
    end 
end 

这里的控制器:

# file: app/controllers/searches_controller.rb 
class SearchesController < ApplicationController 

    def index 
    unless logged_in? 
     redirect_to login_path, :alert => "You must be logged in to access this page." 
    else 
     @searches = Search.where(:user_id => current_user.id) 
     respond_to do |format| 
     format.html 
     format.json { render json: @searches } 
     end 
    end 
    end 

end 

而这里的ApplicationController的代码。请注意,current_user = x具有记录x in的效果,它很简单:它设置@current_user和session [:user_id]。

# file: app/controllers/application_controller.rb 
class ApplicationController < ActionController::Base 
    protect_from_forgery 
    force_ssl 

    protected 

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

    def current_user=(user) 
    @current_user = user 
    session[:user_id] = user && user.id 
    end 

    def logged_in? 
    [email protected]_user 
    end 

    def require_login 
    unless logged_in? 
     redirect_to login_path, :alert => "You must be logged in to access this page." 
    end 
    end 

    helper_method :current_user, :logged_in?, :require_login 
end 

回答

1

我可能之前已经说过,但如果堆栈溢出了徽章回答了自己的问题,我有徽章的很多! :)

好的,要回答这个问题,你需要看看documentation for ActionController::TestCase。当你这样做,你会发现,它建立绑定:

@controller 
@request 
@response 

所以在OP给出了具体的控制器,写login方法很简单:

# file: spec/controllers_helper.rb 
module ControllersHelper 
    def login(user) 
    @controller.send(:current_user=, user) 
    end 
end 

(难道我听到有人说再次RTFM?我认为是这样...)

相关问题