Platinum Partner

RSpec Testing :on => :create Validations

ISSUE
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!!!
{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}