Setting instance variables for controllers

Hi everyone,

I have been trying to find an answer to this question and have not been
able
to. Any help is greatly appreciated.

I am using Rails 2.1.0 and Rspec 1.1.4.

How can I set an instance variable in my Rspec test that is then
available
to my controller while the test is running? For example:

(I tried to keep this as simple as possible while illustrating what I
mean)

—application_controller.rb—

ApplicationController

before_filter :set_user

def set_user
@user = User.find( 5 )
end

end

—cart_controller.rb—

CartController

def index
if @user
render :action => ‘cart_full’
else
render :action => ‘cart_empty’
end
end

end

—Rspec—

describe CartController do

describe “index” do

it "should render 'cart_full' if @user is set" do
  # This is where I need to set @user
  response.should render_template( : cart_full )
end

it "should render 'cart_empty' if @user is not set" do
  response.should render_template( : cart_empty )
end

end

end

Is this even possible to do?

I thought that controller.set_instance_variable( :@user, … ) would do
the
trick but it does not seem to work.

Thank you!

View this message in context:
http://www.nabble.com/Setting-instance-variables-for-controllers-tp19283500p19283500.html
Sent from the rspec-users mailing list archive at Nabble.com.

You don’t need to set the instance variable, you can stub the find call:

describe CartController do

describe “index” do

before do
@user = mock_model( User )
end

it “should render ‘cart_full’ if @user is set” do
# This is where I need to set @user
User.stub!( :find ).with(‘your-id-param-here’).and_return( @user )
response.should render_template( : cart_full )
end

it “should render ‘cart_empty’ if @user is not set” do
response.should render_template( : cart_empty )
end

end

end

On Wed, Sep 3, 2008 at 11:22 AM, patrick_r
[email protected] wrote:

@user = User.find( 5 )
if @user

 response.should render_template( : cart_empty )

I thought that controller.set_instance_variable( :@user, … ) would do the
http://rubyforge.org/mailman/listinfo/rspec-users


Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)
João Pessoa, PB, +55 83 8867-7208

On Sep 3, 2008, at 10:40 AM, Maurício Linhares wrote:

You don’t need to set the instance variable, you can stub the find
call:

Or you could also stub the call to User::find.

Also - you don’t WANT to set the instance variable - it’s an
encapsulation violation - there is nothing in the public interface
about it. Remember, these are not only specs, but examples. Would
you want someone writing production code modeled off of that spec?

Scott

On Sep 3, 2008, at 10:53 AM, Scott T. wrote:

encapsulation violation - there is nothing in the public interface
about it. Remember, these are not only specs, but examples.
Would you want someone writing production code modeled off of that
spec?

Scott

Often I’ll encapsulate important instance variables (especially ones
assigned in before_filters) in a method, like current_user,
current_project, etc.

 def current_project
     @project
 end

Then these are easily stubbed in specs.

controller.stub!(:current_project).and_return(project)

Further, I usually mock the entire before_filter methods

before_filter :find_project

with a shared method like

def mock_find_project
project = @project || mock_project
controller.stub!(:find_project).and_return(project)
controller.stub!(:current_project).and_return(project)
project
end

Lastly, I maintain the find_project method in application.rb so it
can be shared among controllers, and tested separately. (either with
shared behaviors, or in my case i’ve rigged up an
application_controller_spec that lets me test methods in
application.rb independent of a specific controller).

–linoj

Thank you very much for all your help, this made everything crystal
clear!


View this message in context:
http://www.nabble.com/Setting-instance-variables-for-controllers-tp19283500p19295990.html
Sent from the rspec-users mailing list archive at Nabble.com.