Search code examples
ruby-on-railsrubytestingrspecrspec-rails

Rails: RSpec: using global path variables only seems to work within "it" blocks


While following Michael Hartl's Rails tutorial, I was experimenting with some custom functions in my test section, and ran into a restriction that surprised me. Basically, global path variables (eg "root_path") only work within the "do...end" block of an "it" section within a "describe" block of the RSpec tests.

I believe the following details boil down to the question, what is special about the "it" block which enabled "root_path" to work there while not working outside of the "it" block?

(I've determined a workaround, but I'm curious whether there's a solid explanation of this behavior.)

File: spec/requests/static_pages_spec.rb

This fails:

require 'spec_helper'

def check_stable(path)
  it "should be stable" do
    get path
    response.status.should be(200)
  end
end

describe "StaticPages" do
  describe "Home => GET" do
    check_stable(root_path)
  end
end

This succeeds:

require 'spec_helper'

describe "StaticPages" do
  describe "Home => GET" do
    it "should be stable" do
      get root_path
      response.status.should be(200)
    end
  end
end

The failure is basically:

$ bundle exec rspec spec/requests/static_pages_spec.rb
Exception encountered: #<NameError: undefined local variable or method `root_path' for #<Class:0x00000004cecd78>>

... any idea why?

I tried all of the suggestions on these two threads:

Hartl's Tutorial Section 5.3.2: Rails Routes

Rspec and named routes

None worked until I sussed out the issue above.


Solution

  • Yes, named routes work only within it or specify blocks. But it's easy to modify the code:

    def should_be_stable(path)
      get path
      response.status.should be(200)
    end
    
    describe "StaticPages" do
      describe "Home => GET" do
        it { should_be_stable(root_path) }
      end
    end
    

    You steel need to include url_helpers