Rspec: How to assign instance variable in controller spec
instance_eval
is a relatively clean way to accomplish this:
describe TestController do
it "test some_method" do
phone = Phone.new(...)
controller.instance_eval do
@my_variable = phone
end
controller.send(:some_method).should be_true
end
end
In this case, using do...end
on instance_eval
is overkill, and those three lines can be shortened to:
controller.instance_eval {@my_variable = phone}
I don't think you want to access an instance variable from your spec controller, as the spec should test the behaviour, but you can always stub the private method. In your case it should be something like this (in this example it doesn't make so much sense):
describe TestController do
it "test some_method"
phone = Phone.new(...)
controller.stub(:some_method).and_return(true)
controller.send(:some_method).should be_true
end
end
If this is not what you are looking for take a look at this: How to set private instance variable used within a method test?
When testing private methods in controllers, rather than use send
, I tend to use an anonymous controller due to not wanting to call the private method directly, but the interface to the private method (or, in the test below, effectively stubbing that interface). So, in your case, perhaps something like:
require 'spec_helper'
describe TestController do
controller do
def test_some_method
some_method
end
end
describe "a phone test with some_method" do
subject { controller.test_some_method }
context "when my_variable is not nil" do
before { controller.instance_variable_set(:@my_variable, Phone.new(...)) }
it { should be_true }
end
context "when my_variable is nil" do
before { controller.instance_variable_set(:@my_variable, nil) }
it { should_not be_true } # or should be_false or whatever
end
end
end
There's some good discussion on the issue of directly testing private methods in this StackOverflow Q&A, which swayed me towards using anonymous controllers, but your opinion may differ.