Reputation: 1004
I am having trouble with devise validation. This is my model class (Note that I have enabled validatable
):
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :recoverable,
:rememberable, :trackable, :validatable
end
And I try to validate the password confirmation using:
describe User do
before { @user = FactoryGirl.build(:user) }
subject { @user }
it { should validate_confirmation_of(:password) }
end
My factory:
FactoryGirl.define do
factory :user do
email { FFaker::Internet.email }
password "12345678"
password_confirmation "12345678"
end
end
But i got this error:
1) User should require password_confirmation to match password
Failure/Error: it { should validate_confirmation_of(:password) }
Expected errors to include "doesn't match Password" when password is set to "different value",
got no errors
# ./spec/models/user_spec.rb:18:in `block (2 levels) in <top (required)>'
Which means the devise validator is not triggered.
Now I add a custom validator:
validate :password_must_match
def password_must_match
errors.add(:password, "doesn't match confirmation") if password != password_confirmation
end
And got this error:
Failures:
1) User should require password_confirmation to match password
Failure/Error: it { should validate_confirmation_of(:password) }
Expected errors to include "doesn't match Password" when password is set to "different value",
got errors:
* "doesn't match Password" (attribute: password_confirmation, value: "some value")
* "doesn't match confirmation" (attribute: password, value: "different value")
# ./spec/models/user_spec.rb:18:in `block (2 levels) in <top (required)>'
As you can see, we now have 2 validation errors, "doesn't match Password"
is from devise's validatable
, and "doesn't match confirmation"
is from my own custom validator.
I also tried using a custom test instead of it { should validate_confirmation_of(:password) }
describe "#confirmation_of_password" do
it "should fail when password does not match" do
expect { User.create!(email: "[email protected]", password: "123456", password_confirmation: "1234567") }.to raise_error
end
end
And it works. But I dont wanna reinvent the wheel from shoulda
Upvotes: 1
Views: 891
Reputation: 3285
In your first test You expect that it will validate confirmation of password but you pass in the same password so it never gets a chance to fail. SO you have 3 options. 1 use your first test but change the confirmation to not be the same(by passing in the params via factory girl). 2 you can expect to raise(if you do this you should specify which error will raise). Or you can also use Factory Girl's build method and expect the user to not be valid.
Upvotes: 1