Post on 04-Aug-2015
RSpec Tips• Configuration: Color, Verbose
• Alias bundle exec
• description text should build the user story
• add comments to your end statements
Description Text builds a User StoryTagsController when authorized User (admin) the DELETE #destroy action behaves like a 302 redirect request action redirects to :back (root_path)
RSPec Gotchas• Scoping is weird it_behaves_like "a 302 redirect request action", ":back (root_path)" do let!(:put_update) {put :update, id: @user.id, user: @user_attributes} let(:redirect_path) {root_path}end
• Relish Docs
How to RSpecOO BB Object Oriented Black Box
• Given (Context)
• When (Event)
• Then (Expected Result)
let :examplelet!(:post_create) {post :create, user: @user_attributes}let(:redirect_path) {root_path}
shared examples: 3 types of RESTful responses• successful GET action
• redirect 302 action
• unauthorized action 302 redirect
successful GET actionRSpec.shared_examples_for 'an unauthorized action' do it "responds redirect with an HTTP 302 status code" do expect(response).to be_redirect expect(response).to have_http_status(:found) end it "provides a flash alert message" do expect(flash[:warning]).to_not be_nil end it "redirects to login_path" do expect(response).to redirect_to login_path endend
redirect 302 actionRSpec.shared_examples_for "a 302 redirect request action" do |path_name| it "responds with a redirect HTTP 302 status code" do expect(response).to be_redirect expect(response).to have_http_status(:found) end it "redirects to #{path_name}" do expect(response).to redirect_to redirect_path endend
unauthorized action 302 redirectRSpec.shared_examples_for 'an unauthorized action' do it "responds redirect with an HTTP 302 status code" do expect(response).to be_redirect expect(response).to have_http_status(:found) end it "provides a flash alert message" do expect(flash[:warning]).to_not be_nil end it "redirects to login_path" do expect(response).to redirect_to login_path endend
require 'support/controller_helper'
describe UsersController do context 'when unauthorized (no User)' do describe "the GET #new action" do end # describe "the GET #new action" do describe "the POST #create action" do context "is provided valid User params and" do end # context "is provided valid User params and" do context "is provided invalid User params and" do end # context "is provided invalid User params and" do end # describe "the POST #create action" do describe "the GET #show action" do end # describe "the GET #show action" do end # context 'when unauthorized (no User signed in)' do
context 'when authorized (Admin User)' do describe "the GET #index action" do end #describe "the GET #index action" do describe "the PUT #update action" do context "is provided valid user params and" do end # "is provided valid user params and" do context "is provided invalid user params and" do end # "is provided invalid user params and" do end # "the PUT #update action" do end # context 'when authorized (Admin User)' doend
Unauthorized Actiondescribe "the GET #show action" do before :example do @user = create(:user) end
it_behaves_like 'an unauthorized action' do let!(:get_show) {get :show, {id: @user.id}} endend # describe "the GET #show action" do
GET #showdescribe "the GET #show action" do before :example do @user = create(:user) end
it_behaves_like "a successful GET action", :show do let!(:get_show) {get :show, {id: @user.id}} end
let(:get_show) {get :show, {id: @user.id}}
it "assigns a valid UserDecorator of to @user" do get_show @decorated_user = UserDecorator.new @user expect(assigns(:user)).to be_kind_of(UserDecorator) expect(assigns(:user)).to eq(@decorated_user) endend # describe "the GET #show action" do
GET #indexdescribe "the GET #index action" do
it_behaves_like "a successful GET action", :index do let!(:get_index) {get :index} end
let(:get_index) {get :index}
GET #index con'd it "loads the users in the current users, current region" do region = create(:region) user1, user2 = create(:user), create(:user) [@admin, user1, user2].each do |u| u.add_to_region! region u.current_region = region u.save end get_index expect(assigns(:users)).to match_array([@admin.reload, user1.reload, user2.reload]) endend #describe "the GET #index action" do
GET #newdescribe "the GET #new action" do it_behaves_like "a successful GET action", :new do let!(:get_new) {get :new} end
let!(:get_new) {get :new}
it "assigns a unsaved User to @user" do expect(assigns(:user)).to be_kind_of(User) expect(assigns(:user)).to respond_to(:id).with(nil) endend # describe "the GET #new action" do
POST #createdescribe "the POST #create action" do before :example do @user_attributes = attributes_for(:user) request.env["HTTP_REFERER"] = root_path end
let(:post_create) {post :create, user: @user_attributes}
POST #create con't context "is provided valid User params and" do it_behaves_like "a 302 redirect request action", ':back (to root_path)' do let!(:post_create) {post :create, user: @user_attributes} let(:redirect_path) {root_path} end
it "creates a user" do expect { post_create }.to change(User, :count).by(1) end it "provides a flash success message" do post_create expect(flash[:success]).to_not be_nil end
end # context "is provided valid User params and" do
POST #create con't con't context "is provided invalid User params and" do before :example do @user_attributes = attributes_for(:user) User.create @user_attributes end
it_behaves_like "a 302 redirect request action", 'new_user_path' do let!(:post_create) {post :create, user: @user_attributes} let(:redirect_path) {new_user_path} end
it "fails to create a new user" do expect { post :create, user: @user_attributes }.not_to change(User, :count) end it "provides a flash danger message" do post_create expect(flash[:danger]).to_not be_nil end end # context "is provided invalid User params and" doend # describe "the POST #create action" do
GET #editdescribe "the GET #edit action" do before :example do @user = create(:user) end
it_behaves_like "a successful GET action", :edit do let!(:get_edit) {get :edit, {id: @user.id}} end
let(:get_edit) {get :edit, {id: @user.id}}
it "loads all of the roles from User class into @roles" do roler = class_double("User") allow(roler).to receive(:roles).and_return([:worker, :manager, :organizer, :moderator, :admin]) get_edit expect(assigns(:roles)).to match_array([:worker, :manager, :organizer, :moderator, :admin]) end
GET #edit con't it "loads all of the regions from Region class into @regions" do region1, region2 = create(:region), create(:region) get_edit expect(assigns(:regions)).to match_array([region1, region2]) end it "assigns valid UserDecorator to @user" do get_edit @decorated_user = UserDecorator.new @user expect(assigns(:user)).to be_kind_of(UserDecorator) expect(assigns(:user)).to eq(@decorated_user) endend # describe "the GET #edit action" do
PATCH #updatedescribe "the PUT #update action" do
let(:put_update) {put :update, id: @user.id, user: @user_attributes}
context "is provided valid user params and" do before :example do @user_attributes = attributes_for(:user).merge({email: "vengeful_spirit@example.com"}) @user = User.create @user_attributes.merge({email: "sneaky_jugger@example.com"}) end
it_behaves_like "a 302 redirect request action", "@user" do let!(:put_update) {put :update, id: @user.id, user: @user_attributes} let(:redirect_path) {@user} end
PATCH #update con't it "changes user email attribute" do expect(@user.reload.email).to eq("sneaky_jugger@example.com") put_update expect(@user.reload.email).to eq("vengeful_spirit@example.com") end it "provides a flash success message" do put_update expect(flash[:success]).to_not be_nil end end # "is provided valid user params and" do
PATCH #update con't con't context "is provided invalid user params and" do before :example do @user_attributes = attributes_for(:user).merge({email: "vengeful_spirit.example.com"}) @user = User.create @user_attributes.merge({email: "sneaky_jugger@example.com"}) request.env["HTTP_REFERER"] = root_path end
it_behaves_like "a 302 redirect request action", ":back (root_path)" do let!(:put_update) {put :update, id: @user.id, user: @user_attributes} let(:redirect_path) {root_path} end
PATCH #update con't con't con't it "fails to change user email attribute" do expect(@user.reload.email).to eq("sneaky_jugger@example.com") put_update expect(@user.reload.email).to eq("sneaky_jugger@example.com") end it "provides a flash danger message" do put_update expect(flash[:danger]).to_not be_nil end end # "is provided invalid user params and" doend # "the PUT #update action" do
DELETE #destroydescribe "the DELETE #destroy action" do before :example do @tag = create(:tag) request.env["HTTP_REFERER"] = tags_path end
let(:delete_destroy) {delete :destroy, id: @tag.id }
it "destroys @tag" do expect {delete_destroy}.to change(Tag, :count).by(-1) end
it_behaves_like "a 302 redirect request action", "tags_path (:back)" do let!(:delete_destroy) {delete :destroy, id: @tag.id } let(:redirect_path) {tags_path} endend
Resources• Everyday Rails: How I learned to test my Rails applications
• Relish: RSpec Docs
• Code School: Testing with RSpec
• Code Examples