Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3.1 Rspec Creating test case validate field for Model

I'm trying to create a test case for User model. Basically, it will validate first_name and last_name to be present.

What I am trying to do is to check whether the error on a specific field is empty or not and it should be empty. However it always fails.

What is the correct way to do this?

Here is my code

On my user_spec.rb

require 'spec_helper'

describe User do

  before do
    @user = User.new
  end

  it "must have a first name" do
    @user.errors[:first_name].should_not be_empty
  end

  it "must have a last name" do
    @user.errors[:last_name].should_not be_empty
  end
end

On my user.rb file

class User < ActiveRecord::Base
  validates :first_name, :presence => true
  validates :last_name, :presence => true
end
like image 664
user181677 Avatar asked Nov 28 '22 03:11

user181677


2 Answers

You can test by simply doing this as well:

describe 'validations' do
  it { should validate_presence_of :firstname }
  it { should validate_presence_of :lastname  }
end

Take a look at the shoulda matchers for all such standard Rails Validation. This way is not just more concise but also takes care of the positive case. Meaning you then dont need to test the scenario mentioned below:

it "passed validations when first_name is set"
  user = User.create(:firstname => 'f', :lastname => 'l')
  user.errors[:first_name].should be_empty
  user.errors[:last_name].should be_empty
end
like image 135
jake Avatar answered Nov 29 '22 15:11

jake


RSpec supports the notion of an "implicit" subject. If your first argument to the "describe" block is a class, RSpec automatically makes an instance of that class available to your specs. See http://relishapp.com/rspec/rspec-core/v/2-6/dir/subject/implicit-subject.

require 'spec_helper'

describe User do

  it "must have a first name" do    
    subject.should have(1).error_on(:first_name)
  end

  it "must have a last name" do
    subject.should have(1).error_on(:last_name)
  end
end

which results in RSpec output (if using --format documentation) of:

User
  must have a first name
  must have a last name

You can abbreviate it even further if you are content with the RSpec output defaults:

require 'spec_helper'

describe User do
  it { should have(1).error_on(:first_name) }
  it { should have(1).error_on(:last_name) }
end

which results in:

User
  should have 1 error on :first_name
  should have 1 error on :last_name
like image 27
Phil Misiowiec Avatar answered Nov 29 '22 16:11

Phil Misiowiec