9

I'm writing some unit tests to ensure a User model cannot have a password < 8 characters long.

I started with a User model:

class User < ActiveRecord::Base
  ...
  validates :password, :length =>{
    :minimum => 90,
    :too_short => "password is too short, must be at least %{count} characters"
  }, :on => :create

end

And a user_spec.rb test:

describe User do
  subject { FactoryGirl.build :user }

 its(:password) { should have_at_least(8).items }
end

However I realised that this doesn't actually test my validation, it just tests that my factory had a password >= 8 characters.

Is there a nice way to do this other than testing the valid? method for 0-7 character passwords?

My theory is that if I only test for 7 characters and someone accidentally hard codes that 4 characters passwords are OK this would pass validation but isn't really what was intended. There could be some code else where that depends on a password being more than 8 characters (not likely but in other situations could be true) and so allowing a password of 4 is incorrect.

In this case the person who changed the password validation in the model won't know that that they've done anything wrong.

I'd just like to know how to properly test situations like this nicely with TDD.

1
  • I don't understand your problem.. Commented Oct 28, 2012 at 17:53

2 Answers 2

20

Using the ensure_length_of matcher in thoughtbot's shoulda matchers, you can do this:

describe User do
  it { should validate_length_of(:password).is_at_least(8)
                                         .with_message(/password is too short/) }
end

See also: How can I test :inclusion validation in Rails using RSpec

Sign up to request clarification or add additional context in comments.

1 Comment

ensure_length_of is now deprecated. Use validate_length_of instead.
2

I don't know if this answers your question but I think you are safe with something like this:

class User < ActiveRecord::Base
  validates :password, :length => {:minimum => 8 }
end

describe User do
  it "validates password length" do
    FactoryGirl.build(:user, password: "1234567").should_not be_valid
    FactoryGirl.build(:user, password: "12345678").should be_valid
  end
end

The reason is that for this test to let through a 4 character password somebody would have to have set a validation rule that says 4 characters is ok, 7 isn't ok, but 8 is ok. Not something that is likely to happen by accident.

1 Comment

This is effectively what we already have. "Not something likely" mean it's still possible and is what were trying to work out how to avoid. Thanks though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.