How do I mock out the before :login_required method?

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.[]=

On 13.2.2008, at 5.12, Wes S. wrote:

def do_get

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 L.

http://www.railsecommerce.com
http://odesign.fi

On Feb 13, 2008 6:52 AM, Max W. [email protected]
wrote:

Looking at my log file, the :login_required filter is still failing, so it
looks like my stub has missed its target. How do i call it on the actually
controller? I’ve seen in another thread that “I can get the controller from
my specs” but i don’t know exactly what’s meant by that.

There is a method named controller that you can call to access the
controller from within the spec:

controller.stub!(:whatever …)

HTH,
David

I’m having a similar problem - my application controller has the
UserSystem
module included, and that’s where the login_required method lives. In a
spec for another controller, which has before_filter :login_required,
i’m
trying to stub the login_required method to just return true, but i
think my
problem is that i’m calling it on the class instead of an instance of
ApplicationController:

ApplicationController.stub!(“login_required”).and_return(true)

Looking at my log file, the :login_required filter is still failing, so
it
looks like my stub has missed its target. How do i call it on the
actually
controller? I’ve seen in another thread that “I can get the controller
from
my specs” but i don’t know exactly what’s meant by that.

View this message in context:
http://www.nabble.com/How-do-I-mock-out-the-before-%3Alogin_required-method--tp15448454p15456464.html
Sent from the rspec-users mailing list archive at Nabble.com.

On Feb 13, 2008 6:03 PM, Wes S. [email protected] wrote:

have so far that doesn’t work. Any help would be most appreciated.

The error occurred while evaluating nil.[]=
for that. So in a view spec corresponding to my previous example, you
@current_user = mock_user({:roles => [@role]})
template.stub!(:current_user).and_return(@current_user)

rspec-users mailing list
[email protected]
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.

Jarkko L. wrote:

require File.dirname(FILE) + ‘/…/spec_helper’

it “should be successful” do

What do you expect the assigns[:… lines to do? If you mean to use
“assigns[:foo] = ‘bar’” in your before block.
[:admin, :organizer, :client, :teacher].each do |r|
end
http://jlaine.net
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)?

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

David C. wrote:

login_required method so that my GroupController actions don’t get
@group = mock_model(Group)

end

You have a nil object when you didn’t expect it!
other hand, in the view specs you do need a way to set instance
def login_as(role)
else
//jarkko

# mock and stub the Group model methods

def do_get


rspec-users mailing list
[email protected]
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)

David C. wrote:

On 13.2.2008, at 5.12, Wes S. wrote:
require File.dirname(FILE) + ‘/…/spec_helper’

it “should be successful” do

What do you expect the assigns[:… lines to do? If you mean to use
“assigns[:foo] = ‘bar’” in your before block.
[:admin, :organizer, :client, :teacher].each do |r|
end
http://jlaine.net
http://rubyforge.org/mailman/listinfo/rspec-users

since this is a secured controller, we have to mock the security

it “should be successful” do

http://rubyforge.org/mailman/listinfo/rspec-users

Well, it seems so clear when you write the code for me :slight_smile: Thank you for
your time and help.

Wes

On Feb 13, 2008 6:24 PM, Wes S. [email protected] wrote:

since this is a secured controller, we have to mock the security

end
them as url parameters, you have to pass them to the get method

@current_user.stub!(:has_role?).with(r).and_return(role == r ?
end
http://dotherightthing.com

system too
do_get

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