Discussion:
Setting instance variables for controllers
patrick_r
2008-09-03 14:22:20 UTC
Permalink
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.
Maurício Linhares
2008-09-03 14:40:51 UTC
Permalink
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
Post by patrick_r
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
(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
render :action => 'cart_full'
else
render :action => 'cart_empty'
end
end
end
---Rspec---
describe CartController do
describe "index" do
response.should render_template( : cart_full )
end
response.should render_template( : cart_empty )
end
end
end
Is this even possible to do?
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.
_______________________________________________
rspec-users mailing list
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
Scott Taylor
2008-09-03 14:53:14 UTC
Permalink
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
Jonathan Linowes
2008-09-03 15:29:39 UTC
Permalink
Post by Scott Taylor
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
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
Post by Scott Taylor
_______________________________________________
rspec-users mailing list
http://rubyforge.org/mailman/listinfo/rspec-users
patrick_r
2008-09-03 19:12:02 UTC
Permalink
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.
Continue reading on narkive:
Loading...