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)

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)

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to