Rspec / Guard / FactoryGirl returns undefined method error
First, I have a valid factory / model and this particular test is going through the console.
model
validate :some_condition
def some_condition
errors.add(:attribute, "cannot be less than 5") if self.attribute < 5
end
test
it "should not allow values above 5" do
model = FactoryGirl.create(:model) # creates valid model
model.attribute = 10
model.valid?.should be_false
end
In the console:
model = FactoryGirl.create(:model)
model.attribute = 10
model.valid? # => false
In rspec
undefined method `<' for nil:NilClass
I can't figure out why this is happening. Obviously it has something to do with it self.attribute
, but why does this work on console but not in tests? attribute
by itself also returns the same error and I checked: self is defined as a model instance. Regardless, this does not explain the inconsistency. It works in the console with exactly the same model and attributes.
To note: I have restarted all environments, this is based on a fresh reboot.
Update
In desperation, I deduced attribute
in several contexts before this condition and then exit
. This led to even stranger results. Work on this:
def some_condition
puts self.attribute # => returns blank in test, attribute value otherwise
puts "#{self.attribute}" # => returns attribute value in test!!!
exit
errors.add(:attribute, "cannot be less than 5") if self.attribute < 5
end
The above made me incredibly tense. Do I now need tests to test my tests? really hope someone more proficient with ruby or the aforementioned tools have a logical explanation for this mess because i am completely lost.
This leads to this abomination:
errors.add(:attribute, "cannot be less than 5") if self.attribute < 5
# => IN TESTS self.attribute returns nil
errors.add(:attribute, "cannot be less than 5") if "#{self.attribute}".to_i < 5
# => IN TESTS self.attribute returns value! This works!?
Where do you turn? Is it ruby, rails, factory girl, rspec?
FIX
After this massive question crash, it turned out I forgot rake db:test:prepare
after a little migration. I still don't understand how this could cause such a problem. Lesson learned. Run migrations in different environments and find the best debugger!
source to share
RSpec syntax has changed slightly from version 1 to version 2 and this can be confusing.
Could you please tell me what happens if you write your test this way?
it "should not allow values above 5" do
model = build(:model, :attribute => 10)
model.should_not be_valid
model.should have(1).error_on(:attribute)
end
The reason I'm using build
and not create
is that you can test your checks without hitting the database.
source to share