manijain
manijain

Reputation: 119

how can use hash variables with rspec capybara test specification

My spec file:

require 'spec_helper'

describe "State Contracts page" do 
  @state_data = {
   :state_slug => 'Alabama', 
   :state_name => 'California'
  }

 before(:each) { visit state_path(:state=>"#{@state_data[:state_slug]}" )}

 it 'should have header' do
   page.should have_content("#{@state_data[:state_name]} Contracts")
 end

# show statistics specification for State Contract
 it "should have #{@state_data[:state_name]} Statistics details" do
    page.should have_content("#{@state_data[:state_name]} Statistics") 
    page.should have_content('Total Obligated Amount')
    page.should have_content('Total Transactions')
    page.should have_content('Total Contractors')
    page.should have_content('Total Contract Recipients')
    page.should have_content('Total Offers')
  end
end

# show State link  
it "should have visible #{@state_data[:state_name]} Links" do
    page.should have_content("#{@state_data[:state_name]} Links")
    assert_equal(true, find_link("Agencies in #{@state_data[:state_name]}").visible?)
    assert_equal(true, find_link("Contractors in "{@state_data[:state_name]}").visible?)
    assert_equal(true, find_link("Contracts in #{@state_data[:state_name]}").visible?)
  end
end

After when I run the test, I got next Error:

undefined method `[]' for nil class for "#{@state_data[:state_name]}"

I think i am interpolating hash variable but now not getting right.

Upvotes: 2

Views: 3843

Answers (2)

Peter Alfvin
Peter Alfvin

Reputation: 29419

Local variables or instance variables defined in a describe block are not accessible in any contained it blocks.

If you want to make arbitrary variables or methods available across multiple it blocks, you need to use let, let! or before. The let methods let you memoize helper methods while the before method let's you execute arbitrary Ruby code prior to executing the it block. The subject method is also available as means of defining the subject helper.

Of course, you can also define methods or variables within each it block.

Upvotes: 1

Eric C
Eric C

Reputation: 2205

You can't use instance variables in an it block without declaring it somewhere in a before. Wrap @state_data in your before(:each) block and it should work.

It would look like the following:

before do
  @state_data = {
    :state_slug => 'Alabama', 
    :state_name => 'California'
  }
  visit state_path(:state=>"#{@state_data[:state_slug]}"
end

My understanding is that using instance variables is considered an antipattern and you should consider using let() or subject() instead

Using let() would change this to:

let(:state_data) do
  { 
    :state_slug => 'Alabama', 
    :state_name => 'California'
  }
end

before { visit state_path(:state=>"#{state_data[:state_slug]}" }

it 'should have header' do
  page.should have_content("#{state_data[:state_name]} Contracts")
end

Upvotes: 4

Related Questions