Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing password length validation with RSpec

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.

like image 999
Sarah Tattersall Avatar asked Oct 28 '12 17:10

Sarah Tattersall


2 Answers

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

like image 111
Chris Salzberg Avatar answered Oct 20 '22 18:10

Chris Salzberg


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.

like image 34
Derek Hill Avatar answered Oct 20 '22 19:10

Derek Hill