FactoryGirl gives no useful validation errors
I use FactoryGirl for my fixtures and find it doesn't really give useful validation errors.
I always get a message for activerecord.errors.models.messages.record_invalid.
Not sure what additional data is needed to diagnose this. This makes it an excruciatingly slow process to track down every bug.
Factory example:
Factory.define :partner do |partner|
partner.sequence(:username){ |n| "amcconnon#{n}" }
partner.first_name "Bobby Joe"
partner.last_name "Smiley"
partner.sequence(:email){ |n| "bob{n}@partners.com" }
partner.phone_number "5557 5554"
partner.country_id 75
partner.password "password"
partner.password_confirmation "password"
end
Then Factory (: partner) => "ActiveRecord :: RecordInvalid Exception: It looks like something went wrong with these changes"
The actual problem is of course the email sequence is not using n correctly and there is a unique email validation. But this is for illustrative purposes.
rails => 3.2.2 factory_girl 2.6.1
Any other tools needed to diagnose this?
(Note: edited this just to add an easier to read factory)
EDIT:
As per bijan's comment: "What exactly am I trying to do."
Attempts to run "rspec spec". I would like when I use factory as Factory (: partner) in this case for an error message when it may not contain the same error that I would receive from Partner.new ({blah ...}). Valid? then looked at the validation errors.
source to share
I'm not sure if this is exactly the same problem as yours, but this is the problem I came across with validation error messages not very helpful and I thought it might be helpful for others looking for this problem. Below I came up with. This can be changed to provide different information.
include FactoryGirl::Syntax::Methods
# Right after you include Factory Girl syntax methods, do this:
def create_with_info(*args, &block)
create_without_info(*args, &block)
rescue => e
raise unless e.is_a? ActiveRecord::RecordInvalid
raise $!, "#{e.message} (Class #{e.record.class.name})", $!.backtrace
end
alias_method_chain :create, :info
Then when you use create :model_name
it will always include the model name in the error message. We had some pretty deep dependencies (yes, another problem) and had a validation error like "name is not valid" ... and name
was an attribute for several different models. By using this method, it saves significant debugging time.
source to share
I think the key point here is that when you set up a test, you need to make sure that the code under test is not executed the moment you set the expectation (ie, when you say "must" in Rspec). The particular problem with validation validation, of course, is that validation fails as soon as you try to save the ActiveRecord object; so the test setup shouldn't trigger a save.
Specific suggestions:
1) IMO Factory definitions should contain the minimum information needed to create a valid object and should change as little as possible. If you want to check validations, you can override the checked attribute when instantiating a new test object.
2) When checking validation use Factory.build
. Factory.build
creates an instance of ActiveRecord with the specified attributes, but does not try to save it; this means that you can pause the test run until you set the expected value in the test.
How about something like this?
it "should fail to validate a crap password" do
partner_with_crap_password = Factory.build(:partner, :password => "crap password")
partner_with_crap_password.should_not be_valid
end
source to share