David Chelimsky wrote: > On Feb 13, 2008 6:24 PM, Wes Shaddix <[EMAIL PROTECTED]> wrote: > >> David Chelimsky wrote: >> >> On Feb 13, 2008 6:03 PM, Wes Shaddix <[EMAIL PROTECTED]> wrote: >> >> >> Jarkko Laine wrote: >> >> >> 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 >> end >> >> This 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 >> >> >> ------------------------------------------------------------------------ >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> >> So, if I update my code to the following, I still get an exception, >> although it is a different one. I really wish I understood how to >> determine the actual call chain that is going on ... what object is nil >> in this case (see error message below the code)? >> >> It should give you a file/line number, which should point you to the >> offensive line. FWIW, this is the same message you'd get using any >> framework, as it comes from Rails, not RSpec. >> >> >> >> 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) >> controller.stub!(:login_required).and_return(:true) >> controller.stub!(:current_user).and_return(@current_user) >> end >> >> def do_get >> get :index >> end >> >> it "should be successful" do >> do_get >> puts response.headers >> response.should be_success >> end >> >> end >> >> Exception : RuntimeError in 'GroupsController should be successful' >> Called id for nil, which would mistakenly be 4 -- if you really wanted >> the id of nil, use object_id >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> >> Gotcha ... this is the offending line in my GroupsController >> >> @groups = Group.search_with_paginate(params[:page], params[:search], >> @current_user.id) >> > > > This is referencing the @current_user instance variable here, not the > current_user method. > > >> Which I'm sure is the @current_user.id. Where I'm confused is that I >> thought the following line in my GroupsController_spec would intercept this >> call and return the mock current_user instance: >> >> @current_user = mock_model(User, :id => 1) >> controller.stub!(:login_required).and_return(:true) >> controller.stub!(:current_user).and_return(@current_user) >> > > > And this is stubbing the current_user method. > > So you want to change the line in the controller to: > > @groups = Group.search_with_paginate(params[:page], params[:search], > current_user.id) > > Cheers, > David > > >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> >> > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > Well, it seems so clear when you write the code for me :) Thank you for your time and help.
Wes _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users