Basic Rspec Test Coverage in Rails
Basic Rspec Test Coverage Model Associations
How to do Rspec Test Coverage in Rails Models :
This section covers the basic Rspec test coverage for rails models. Basically, we need to write test coverage to the following areas.
- Model Associations
- Validations
- Mass assignments (attr_accessible)
- callbacks
- custom validations
Model Associations
In Rails, an association is a connection between two Active Record models, we need to test first if the models associated with the specified models or not?
Rails supports six types of associations:
- belongs_to
- has_one
- has_many
- has_many :through
- has_one :through
- has_and_belongs_to_many
belongs_to :
Example 1:
belongs_to :currency
we can write the Rspec for belongs_association like this,
it { should belong_to(:user) }
Example 2:
belongs_to :home_team, :class_name => ‘Team’
it can be tested like..
it { should belong_to(:home_team).class_name(:team) }
Example 3:
belongs_to :home, :class_name => ‘Team’, :foreign_key => :home_id
it can be tested like..
it { should belong_to(:home).class_name(:team).foreign_key(:home_id) }
has_one :
Example 1:
has_one :build_snapshot
we can write the Rspec test like this,
it { should have_one(:build_snapshot) }
Example 2:
has_one :build_snapshot, :dependent => :destroy
we can write the Rspec test like this,
it { should have_one(:build_snapshot).dependent(:destroy)}
Example 3:
has_one :last_receipt_entered, :class_name => ‘BuildReceipt’
we can write the Rspec test like this,
it { shouldhave_one(:last_receipt_entered).class_name(“BuildReceipt”)}
has_many :
Example 1:
has_many :users
we can write the Rspec test like this,
it { should have_many(:users) }
Example 2:
has_many :users, :dependent => :destroy
we can write the Rspec test like this,
it { should have_many(:users).dependent(:destroy)}
Example 3:
has_many :users, :class_name => ‘Customer’
we can write the Rspec test like this,
it { should have_many(:users).class_name(“Customer”)}
Example 4:
has_many :snapshots, :class_name => ‘ClientSnapshot’,:conditions => [“released_yn = ‘Y’”], :order =>’snapshot_dt DESC’
we can write the Rspec test like this,
it { should have_many(:snapshots).class_name(“ClientSnapshot”).conditions(“released_yn = ‘Y’”).order(“snapshot_dt DESC”)}
has_many :through associations :
Example 1:
has_many :client_cash_receipts, :through => :client_snapshots
we can write the Rspec test like this,
it { should have_many(:client_cash_receipts).through(:client_snapshots) }
has_and_belongs_to_many :
Example 1:
has_and_belongs_to_many, :through => :client_snapshots
we can write the Rspec test like this,
it { should have_and_belong_to_many(:client_cash_receipts) }
has_one :through associations :
Example 1:
has_one :manager, :through => :customers
we can write the Rspec test like this,
it { should have_one(:manager).through(:customers) }
Model Validations :
In Rails, validation is a process to ensure only the valid data is stored into the database.
Validation helpers :
Testing Presence validation with RSpec
Example 1:
validates :name, :presence => true
we can write Rsepec coverage for this validation helper like the below …
it {should validate_presence_of(:name)}
presence with custom message
Example
validates :manager, :presence => { :message => _(“Manager must exist”) }
we can write Rsepec coverage for this validation helper like the below …
it {should validate_presence_of(:manager).with_message(“Manager must exist”)}
Testing length validation with RSpec
Example :
validates :password, :length =>{:minimum => 8,:too_short => “password is too short” }
validates :password, :length =>{:maximum => 8,:too_short => “password is too long” }
we can write Rsepec coverage for this validation helper like the below …
it { should ensure_length_of(:password).is_at_least(8).with_message(/password is too short/) }
it { should ensure_length_of(:password).is_at_least(8).with_message(/password is too long/) }
Testing numericality validation with RSpec
Example :
- validates :age, :numericality => { :greater_than => 18,:only_integer => true }
we can write Rsepec coverage for this validation helper like the below …
it { should validate_numericality_of(:age, :greater_than => 18, :only_integer => true) }
ActiveModel Matchers
Matchers to test validations and mass assignments:
examples :
it { should validate_uniqueness_of(:title) }
it { should validate_uniqueness_of(:title).scoped_to(:user_id, :category_id) }
it { should validate_presence_of(:body).with_message(/wtf/) }
it { should validate_presence_of(:title) }
it { should validate_numericality_of(:user_id) }
it { should ensure_inclusion_of(:status).in_array([‘draft’, ‘public’]) }
Testing Mass assignments with Rspec
t { should allow_mass_assignment_of :some_field }
Testing callbacks
Callbacks are methods that get called at certain moments of an object’s life cycle. we need to test those callbacks in rails models.
It executes whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database
examples
it{ should have_callback(:check_before_destroy).on(:before_destroy) }
it{ should have_callback(:validate_name).on(:before_create) }
it{ should have_callback(:validations_before_destroy).on(:after_create) }
it{ should have_callback(:validate_name).on(:after_save) }
it{ should have_callback(:check_validations).on(:before_validation) }
it{ should have_callback(:validate_name).on(:after_validation) }
but i got an error when i try has_many with class_name and foreign_key
Failure/Error: it { should have_many(:subgroups).class_name("Group").foreign_key(:parent_id) }
NoMethodError:
protected method `foreign_key' called for #
do you know how to resolve it ?