RSpec Testing :on => :create Validations
Join the DZone community and get the full member experience.
Join For FreeISSUE
Having class with validations, for example:
class User < ActiveRecord::Base
...
validates_format_of :email, :with => /some_pattern/,
:on => :create
validates_length_of :email, :within => 5..100,
:on => :create
validates_uniqueness_of :email,
:on => :create
validates_confirmation_of :password,
:on => :create
...
all with :on => :create
option, and trying to test it using RSpec in a common way, like this:
...
it "should not be valid with wrong formated email" do
@user.email = 'b@info'
@user.should_not be_valid # wrong
end
...
it "should not be valid with duplicate user email" do
@user2 = users(:aaron)
@user.email = 'some@email.com'
@user.save
@user.should be_valid # it pass, but not sure of it
@user2.email = @user.email
@user2.save
@user2.should_not be_valid # wrong
end
...
it "should not be valid without password confirmation" do
@user = users(:user_no_pass)
@user.password = 'sikret'
@user.password_confirmation = nil
@user.should_not be_valid # wrong
end
...
it "should not be valid with confirmation not matching password" do
@user.password = 'password'
@user.password_confirmation = 'not confirmed'
@user.should_not be_valid # wrong
...
It all gives wrong output.
SOLUTION
Write a method and put it in a tested class, or in a ActiveRecord::Base, or maybe in a helper:
def valid_on_create?
errors.clear
run_callbacks(:validate_on_create)
validate_on_create
errors.empty?
end
Method valid_on_create?
is taken from ActiveRecord::Base valid?
method. (part of the code).
Now, you can write proper RSpec tests:
...
it "should not be valid with wrong formated email" do
@user.email = 'b@info'
@user.should_not be_valid_on_create
end
...
it "should not be valid with duplicate user email" do
@user2 = users(:aaron)
@user.email = 'some@email.com'
@user.save
@user.should be_valid_on_create
@user2.email = @user.email
@user2.save
@user2.should_not be_valid_on_create
end
...
it "should not be valid without password confirmation" do
@user = users(:user_no_pass)
@user.password = 'sikret'
@user.password_confirmation = nil
@user.should_not be_valid_on_create
end
...
it "should not be valid with confirmation not matching password" do
@user.password = 'password'
@user.password_confirmation = 'not confirmed'
@user.should_not be_valid_on_create
...
NOTE: be_valid_on_create should be used only for validations with :on => :create
option, otherwise it will give wrong results!!!
Opinions expressed by DZone contributors are their own.
Comments