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