[rspec-users] How do I mock out the before :login_required method?

David Chelimsky dchelimsky at gmail.com
Wed Feb 13 18:02:52 EST 2008


On Feb 13, 2008 6:03 PM, Wes Shaddix <wshaddix at gmail.com> 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 => [@role]})
> >
> >     [: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 at 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 at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list