Shoulda Matcher Model Extras
Feb 20, 2013 - Comments
If you use RSpec with your Rails projects, chances are you also use shoulda_matchers (and if you don't, what are you doing with your life?!). You probably already know all about the basic model matchers, like the ones below.
# app/models/user.rb class User < ActiveRecord::Base belongs_to :organization has_many :projects validates :name, :presence => true validates :email, :uniqueness => true end # spec/models/user_spec.rb require 'spec_helper' describe User do context 'associations' do it { should belong_to(:organization) } it { should have_many(:projects) } end context 'validations' do it { should validate_presence_of(:name) } it { should validate_uniqueness_of(:email) } end end
Association Extras
There are a ton of extra options you can use with the association matchers (pretty much any option you can pass to an association). Below are just a few.
# app/models/user.rb class User < ActiveRecord::Base belongs_to :organization, :class_name => 'UserOrganization' has_many :contracts has_many :jobs, :through => :contracts has_many :projects, :order => 'date DESC', :dependent => :destroy accepts_nested_attributes_for :projects, :limit => 3 end # spec/models/user_spec.rb require 'spec_helper' describe User do context 'associations' do it { should belong_to(:organization).class_name('UserOrganization') } it { should have_many(:contracts) } it { should have_many(:jobs).through(:contracts) } it { should have_many(:projects).order('date DESC').dependent(:destroy) } it { should accept_nested_attributes_for(:projects).limit(3) } end end
Validation Extras
There are even more options for use with the validation matchers. Here's a small sampling (including some mass assignment matchers).
# app/models/user.rb class User < ActiveRecord::Base validates :name, :length => { :minimum => 10, :maximum => 100 } validates :email, :format => { :with => /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/ } validates :status, :inclusion => { :in => %w(active inactive suspended) } attr_accessible :name, :email attr_accessible :name, :email, :status, :as => :admin end # spec/models/user_spec.rb require 'spec_helper' describe User do context 'validations' do it { should ensure_length_of(:name).is_at_least(10).is_at_most(100) } it { should validate_format_of(:email).with('user@email.com') } it { should validate_format_of(:email).not_with('user@email') } it { should ensure_inclusion_of(:status).in_array(['active', 'inactive', 'suspended']) } end context 'mass assignment' do it { should allow_mass_assignment_of(:name) } it { should allow_mass_assignment_of(:email) } it { should_not allow_mass_assignment_of(:status) } it { should allow_mass_assignment_of(:status).as(:admin) } end end
These are just a few of the extras that shoulda_matchers offers. I would highly recommend that you read through the documentation to discover all the things you can do.