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.