Reputation: 119
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
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
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