On 13.2.2008, at 5.12, Wes Shaddix wrote:
I have a GroupController class that inherits from a SecuredController which have a before filter (before_filter :login_required). This is using the restul authentication system. I want to mock out the login_required method so that my GroupController actions don't get redirected to /sessions/new but I cant figure it out. Here is what I have so far that doesn't work. Any help would be most appreciated. require File.dirname(__FILE__) + '/../spec_helper' describe GroupsController do before(:each) do # mock and stub the Group model methods @group = mock_model(Group) Group.stub!(:search_with_paginate).and_return(@group)# since this is a secured controller, we have to mock the security system too@current_user = mock_model(User, :id => 1) self.stub!(:login_required).and_return(:false) self.stub!(:current_user).and_return(@current_user) end def do_get get :index end it "should be successful" do assigns[:page] = 1 assigns[:search] = "" do_get puts response.headers response.should be_success end end The error I get is NoMethodError in 'GroupsController should be successful' You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.[]=
What do you expect the assigns[:... lines to do? If you mean to use them as url parameters, you have to pass them to the get method (through do_get in this case). assigns is a hash that contains all the instance variables set in the controllers. So if you say "@foo = "bar"" in your controller action, you can spec it in a controller view like this: assigns[:foo].should == "bar". However, afaik you're not supposed to write into that hash in your controller specs. On the other hand, in the view specs you *do* need a way to set instance variables available in the views, and there you can use the assigns for that. So in a view spec corresponding to my previous example, you would want the instance variable @foo to be there so you would say "assigns[:foo] = 'bar'" in your before block.
That said, I'm not a fan of stubbing the login_required method. Instead, I have created a login_as method in my spec_helper that I use whenever I want to spec something to happen when a logged in user does something (note that I also use the acl_system2 plugin for roles):
def login_as(role) @role = mock_model(Role, :title => role.to_s) @current_user = mock_user({:roles => [EMAIL PROTECTED]) [:admin, :organizer, :client, :teacher].each do |r|@current_user.stub!(:has_role?).with(r).and_return(role == r ? true : false)
end if defined?(controller) controller.send :current_user=, @current_user else template.stub!(:logged_in?).and_return(true) template.stub!(:current_user).and_return(@current_user) end end endThis is a bit simplified but it works for me pretty well with restful_authentication. Normally you would say something like "login_as(:admin)" in a before block in controller and view specs.
//jarkko -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users