Rspec gotcha – instance variables are not cleared between ‘get’s

It seems that (unlike when controller methods are invoked via browser) if you do two consecutive get’s with rspec, instance variables are not cleared with each get, so data crossover is possible.

Here’s a failing test, showing that a variable set in ‘vartest1′ is still present when another controller method ‘vartest2′ is run:

Controller methods:

def vartest1 
  @this_var = "foo" 
  render :text => @this_var
end 
def vartest2 
  render :text => @this_var # should be EMPTY! 
end

Rspec controller spec (note: we use render_views so the views are rendered in the spec)

describe "instance variable crossover example", :focus => true  do 
  describe "THIS PASSES put each get in separate contexts" do 
    it "vartest1 outputs foo" do 
      get "vartest1" 
      response.body.should include("foo") 
    end 
    it "vartest2 does NOT output foo" do 
      get "vartest2" 
      response.body.should_not include("foo") 
    end 
  end 
  describe "THIS FAILS put both gets in SAME context" do 
    it "should not crossover controller instance varables" do 
      get "vartest1" 
      response.body.should include("foo") 
      get "vartest2" 
      response.body.should_not include("foo") # THIS FAILS 
    end 
  end 
end

Rspec results:

instance variable crossover example 
THIS PASSES 

put each get in separate contexts 
vartest1 outputs foo 
vartest2 does NOT output foo 
THIS FAILS 

put both gets in SAME context should not crossover 
controller instance varables (FAILED - 1)

>

What’s happening in the failing test is that when rspec does get ‘vartest1′ the controller method set an instance variable to ‘foo’, and when rspec does get ‘vartest2′ the instance variable (which should be nil) is still set, so the test fails.

Leave a Reply

Your email address will not be published. Required fields are marked *