Learning RSPEC with Rails 4 (Alpha)

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:

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

view raw
user_spec.rb
hosted with ❤ by GitHub

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:

# 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

view raw
controller_spec.rb
hosted with ❤ by GitHub

I’ll cover model, helper and view spec very soon.

Happy Coding 🙂