Testing is a good pratice. You should be doing it. It will make you a better programmer and save you a great deal of headache as your web app grows up. It is especially important when working alongside other programmers. Testing is not perfect though so don’t try to be perfect. Just get started, and you will improve as time goes on.
How should I be testing?
- Using RSpec & factorygirl.
- Testing the Model.
Installation
Add rspec-rails and factorygirl to both the :development and :test groups in the Gemfile:
Initialize the spec/ directory (where specs will reside) with:
1
railsgeneraterspec:install
This adds the following files which are used for configuration:
- .rspec
- spec/spec_helper.rb
- spec/rails_helper.rb
Generators
Once installed, RSpec and factorygirl will generate spec files instead of Test::Unit test files when run commands like: rails generate model and rails generate controller are used.
Example:
1
railsgeneratemodelPost
After you run the command above this adds the following directory and file:
- spec/models/posts.rb
- spec/factories/posts.rb
Let’s get started the Model testing
Assume we have three Models such as post.rb, category.rb, categorization.rb:
post.rb
1234567891011
classPost<ActiveRecord::Basevalidates:title,length:{minimum:10,maximum:100},presence:true,uniqueness:truevalidates:body,length:{minimum:20,maximum:200}validates:status,length:{minimum:2,maximum:20},presence:truevalidates:category_id,presence:truehas_many:categorizationshas_many:categories,through::categorizationsscope:search_by_title,->(title){where("(title like ?) OR title in (?)","%#{title}%",title.split)}end
require'spec_helper'describePost,'validation'doit{shouldensure_length_of(:title).is_at_least(10)}it{shouldensure_length_of(:title).is_at_most(100)}it{shouldvalidate_presence_of(:title)}it{shouldvalidate_uniqueness_of(:title)}it{shouldensure_length_of(:body).is_at_least(20)}it{shouldensure_length_of(:body).is_at_most(200)}it{shouldensure_length_of(:status).is_at_least(2)}it{shouldensure_length_of(:status).is_at_most(20)}it{shouldvalidate_presence_of(:status)}it{shouldvalidate_presence_of(:category_id)}enddescribePost,'association'doit{shouldhave_many(:categorizations)}it{shouldhave_many(:categories).through(:categorizations)}enddescribePost,'column_specification'doit{shouldhave_db_column(:title).of_type(:string).with_options(length:{minimum:10,maximum:100},presence:true,uniqueness:true)}it{shouldhave_db_column(:body).of_type(:text).with_options(length:{minimum:20,maximum:200})}it{shouldhave_db_column(:status).of_type(:string).with_options(length:{minimum:2,maximum:20,presence:true})}it{shouldhave_db_column(:category_id).of_type(:integer)}it{shouldhave_db_index(:title).unique(true)}enddescribePost,'.search_by_name'dobefore(:each)doFactoryGirl.create(:post,title:'Ruby on Rails')endit'returns post that match with title'doPost.search_by_title('Ruby on Rails').count.shouldeql1endit'returns post that like title'doPost.search_by_title('ruby on rails').count.shouldeql1endit'returns post when title is blank'doPost.search_by_title('').count.shouldeql1endit'returns empty when title is not match'doPost.search_by_title('not match').count.shouldeql0endend