Hi Folks,
Hope you all are fine and doing good! I am sure most of you, are using TDD for years now. And, once we think of TDD, the first thing comes into our mind is, RSPEC. We all agree that Rspec is a great framework of Test-Driven-Development and its integration with other libraries (like fixtures etc.) is seamless.
With rapid revolution happening in Rails community, Rspec too has evolved over the years, and my motto is to bring this newly developed RSPEC framework in such a way so that, those who are eager to learn TDD can take tips and take this as a learning material. And those, who are planning to migrate can refer to this!
Environments I am using:
- Ruby 2.1.2
- Rails 4.2.1
- Rspec 3.2.0
Idea is to share small code snippets while learning these changes, where we see: what is new. So let’s explore this now:
1. In Rspec 3, the support for ‘should‘ (e.g. foo.should == bar) is deprecated and is no longer supported. Instead of ‘should’, rspec encourages us to use ‘expect‘. Let’s see how it works:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
class User | |
def initialize(args = {}); end | |
def email | |
'someone@example.com' | |
end | |
def mobile | |
12021679918 | |
end | |
end | |
describe User do | |
describe "#initialize with old should way" do | |
it "should set the email and mobile for user" do | |
u = User.new email: 'someone@example.com', mobile: 12021679918 | |
u.email.should == 'someone@example.com' | |
u.mobile.should == 12021679918 | |
end | |
end | |
describe "#initialize with new expect way" do | |
it "expects email and mobile param for user" do | |
u = User.new email: 'someone@example.com', mobile: 12021679918 | |
expect(u.email).to eq('someone@example.com') | |
expect(u.mobile).to eq(12021679918) | |
end | |
end | |
end |
If you try running this example, you’ll get this deprecation warning message:
Deprecation Warnings:
Using `should` from rspec-expectations‘ old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead
Now, let’s take an example of controller spec. Create a controller with scaffold and write the spec as below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Controller /app/controllers/posts_controller.rb | |
def index | |
@posts = Post.all | |
end | |
# Spec /spec/controllers/posts_controller_spec.rb | |
describe "GET #index" do | |
it "responds successfully with a HTTP 200 status code" do | |
get :index | |
expect(response).to be_success | |
expect(response).to have_http_status(200) | |
end | |
it "should render index template" do | |
get :index | |
expect(response).to render_template('index') | |
end | |
end | |
# Controller /app/controllers/posts_controller.rb | |
def create | |
@post = Post.new post_params | |
respond_to do |format| | |
if @post.save | |
format.html { redirect_to @post } | |
else | |
format.html { render action: :new } | |
end | |
end | |
end | |
# Spec /spec/controllers/posts_controller_spec.rb | |
describe "POST #create" do | |
it "should create new post with valid params" do | |
post :create, post: { title: 'My First Post', description: 'My first post description' } | |
expect(Post.count).to eq(1) | |
end | |
it "redirects to show page once the post is created successfully" do | |
post :create, post: { title: 'My First Post', description: 'My first post description' } | |
expect(response).to redirect_to(Post.first) | |
end | |
it "does not allow to create post without title" do | |
post :create, post: { description: 'My first post description' } | |
expect(Post.count).to eq(0) # This make sure validates :title, presence: true in post.rb | |
end | |
it "renders new template if failed to create post" do | |
post :create, post: { description: 'My first post description' } | |
expect(response).to render_template('new') | |
end | |
end | |
# Controller /app/controllers/posts_controller.rb | |
def update | |
@post = Post.find params[:id] | |
respond_to do |format| | |
if @post.update_attributes(post_params) | |
format.html { redirect_to @post } | |
else | |
format.html { render action: :edit } | |
end | |
end | |
end | |
# Spec /spec/controllers/posts_controller_spec.rb | |
describe "PUT update/:id" do | |
before(:each) do | |
@post = FactoryGirl.create(:post) | |
end | |
it "should render edit template if unable to create post" do | |
@attr = { title: nil, description: 'My first post description' } | |
put :update, id: @post.id, post: @attr | |
expect(response).to render_template('edit') | |
end | |
it "redirects user on show post page" do | |
@attr = { title: 'My First Post', description: 'My first post description' } | |
put :update, id: @post.id, post: @attr | |
expect(response).to have_http_status(302) | |
expect(response).to redirect_to(@post) | |
end | |
it "validates the title and description of post after updation" do | |
@attr = { title: 'My 1st Post', description: 'My 1st post description updated' } | |
put :update, id: @post.id, post: @attr | |
@post.reload | |
expect(@post.title).to eql(@attr[:title]) | |
expect(@post.description).to eql(@attr[:description]) | |
end | |
end |
I’ll cover model, helper and view spec very soon.
Happy Coding 🙂