I've got a test I'm trying to debug and I've noticed that the values are not being set to the user attributes properly. When I run p user.height_feet
or p user.height_inches
from the debug console, I get nil
, when instead I expect the them to return 1
and 8
respectively in the first iteration. p invalid_height.first
and p invalid_height.second
return 1
and 8
properly, however.
Here is the code:
describe "when height is invalid" do
invalid_height = [[1, 8], [8, 2], [5, 13], ['text', 'text'], ['text', 11], [5, 'text'], ['', '']]
invalid_height.each do |invalid_height|
before do
user.height_feet = invalid_height.first
user.height_inches = invalid_height.second
end
it "should not be valid" do
debugger
user.should_not be_valid
end
end
end
And the output at the debug terminal:
(rdb:1) p user.height_feet
nil
(rdb:1) p user.height_inches
nil
(rdb:1) p invalid_height.first
1
(rdb:1) p invalid_height.second
8
Someone in the #rubyonrails IRC channel suggested that it may be a scope issue and asked where my user is defined, saying that my before
and it
blocks may be referring to different users. I didn't think this should be an issue because I have other tests in the same spec file with both before
and it
blocks that run just fine. Thoughts?
You need to think what your code is doing.
It goes through the each and creates a before
and an it "should not be valid"
but these are all eval-ed in the same scope.
So you create a load of before
blocks
before do
user.height_feet = 1
user.height_inches = 8
end
before do
user.height_feet = 8
user.height_inches = 2
end
...
before do
user.height_feet = ""
user.height_inches = ""
end
And you create a load of it
blocks
it "should not be valid" do
debugger
user.should_not be_valid
end
it "should not be valid" do
debugger
user.should_not be_valid
end
...
it "should not be valid" do
debugger
user.should_not be_valid
end
So the result of all of your tests is basically just
before do
user.height_feet = ""
user.height_inches = ""
end
it "should not be valid" do
debugger
user.should_not be_valid
end
Which I believe was not your intent.
The obvious fix is to use a context
block. This will seal each pair of statements into a context.
[[1, 8], [8, 2], [5, 13], ['text', 'text'], ['text', 11], [5, 'text'], ['', '']
].each do |feet, inches|
context "with an invalid height of #{feet} feet, #{inches} inches" do
before do
user.height_feet = feet
user.height_inches = inches
end
it "should not be valid" do
debugger
user.should_not be_valid
end
end
end