Starkers
Starkers

Reputation: 10541

Show model validation errors with rspec

I have one context and 7 expectations in a model spec:

describe User do

    context "with all valid attributes" do
        before { @user = FactoryGirl.build(:user_with_all_valid) }

        subject { @user }

        it { should be_valid }

        its(:first_name) { should == "Jimmy" }
        its(:last_name) { should == "Thehat" }
        its(:profile_name) { should == "Jimbohatboy893" }
        its(:email) { should == "[email protected]" }
        its(:password) { should == "thisisasupersecretpassword12234234" }
        its(:password_confirmation) { should == "thisisasupersecretpassword12234234" }
    end
end

Running this I get some strange results:

14:35:13 - INFO - Running: spec

F......

Failures:

  1) User with all valid attributes should be valid
     Failure/Error: it { should be_valid }
       expected valid? to return true, got false
     # ./spec/model/user_spec.rb:29:in `block (3 levels) in <top (required)>'

Finished in 0.5358 seconds
7 examples, 1 failure

Okay so the validation expectation it { should be_valid } fails. Fair enough, but then why do all the other expectations, testing its first_name, last_name etc pass? If the validation doesn't pass, surely these attributes aren't written to the database and therefore these expectations shouldn't pass? Suspect I have the wrong idea here, they can't be written to the database. I would like to be able to test that though, for peace of mind.

My real question though is debugging. How can I print the validation error messages to the console? expected valid? to return true, got false is only describing the symptoms. I want first_name length too long or similar.

Upvotes: 0

Views: 4387

Answers (2)

Starkers
Starkers

Reputation: 10541

Only a tiny little thing, but based on apneadiving's answer, this gives nice output regarding attributes and their errors:

it 'debugging...' do
    subject.errors.each do |a, e|   
       puts a
       puts e
       puts "----"
    end
end

Upvotes: 0

apneadiving
apneadiving

Reputation: 115511

Sorry to tell but your tests are bad: whats their point? Test your factory's parameters?

What's the added value?

It would make more sense to check your model has fields in db (there are dedicated matchers but this is debatable) or respond_to the methods.

When you're working with an object instance, the fields are set in memory even if they are not persisted, it explains why your tests pass.

To get the errors you should add debug statements or simply check in console why your factory doesnt build valid objects.

it 'debugging...' do
  puts subject.valid?
  puts subject.errors
  # or debugger
  # or binding.pry
  subject.should be_valid
end

Upvotes: 3

Related Questions