Skip to content

Instantly share code, notes, and snippets.

@bonekost
Forked from stevenyap/Rspec.md
Created December 2, 2016 23:52
Show Gist options
  • Save bonekost/dd4d5731662e7992fb69977e7b7dac6f to your computer and use it in GitHub Desktop.
Save bonekost/dd4d5731662e7992fb69977e7b7dac6f to your computer and use it in GitHub Desktop.
Rspec testing cheatsheet

Precaution

  • Example groups are executed in random orders so setting let must be taken care of
  • before(:all) does not rollback transaction! Test data created remains in the test database! However, running rspec (on cmd line) will clear the test database.
    rake db:test:prepare will also clear the test database.

Testing samples:

Feature testing:

click_on "My Deals"
expect(page).to have_content "My Joined Deals"
find("td[data-test='#{delivered_deal.id}']").should have_button "Confirm Delivery"
find("td[data-test='#{undelivered_deal.id}']").should have_content "Pending"

Controller testing:

render_views
assigned(:products)
expect { do_request }.to change(Product, :count).by(1)
response.should render_template :index
response.body.should have_content "Success"
response.body.should have_button "Create Product"

Model testing:

context "Associations" do
  it { should belong_to :category }
end

context "Validations" do
  it { should validate_presence_of :name }
end

# any other model methods

Helper testing:

describe DealsHelper do
  describe "#show_expiry_hours_in_words" do
    it "returns expirys in words with days and hours" do
      expiry_hours = {
          "24" => "1 day",
          "48" => "2 days",
          "49" => "2 days 1 hour",
          "50" => "2 days 2 hours"
      }

      expiry_hours.each do |hours, words|
        helper.show_expiry_hours_in_words(hours).should == words
      end
    end
  end
end

Configuration

  • Add the below to ~/.rspec to format your rspec output in console
--color
--format documentation

Matching

# Controller
response.body.should have_content "Success"
response.body.should have_css '#booking_ta_email[value="ben@example.com"]'
response.body.should have_link "Go to My Bookings", href: bookings_path

Stub a METHOD and tells the testing to return our string

<model>.stub(:var) { "#{Rails.root}/spec/fixture/stub_data.xml" }

# by default, should_receive stubs the method and returns nil
# use and_call_original to make the stub call the original method
HTTParty.should_receive(:post).at_least(3).and_call_original

Quickly create a test data object for testing

double(:asdasd, asking_price: 5) # returns an object with asking_price member

Testing HTTParty with retries

it "attempts url callback at least 3 times" do
  HTTParty.stub(:post).and_raise("Cannot connect")
  HTTParty.should_receive(:post).at_least(3)
  do_request
end

Testing Controller with Views

  • Rspec controller does not load the views so you will get an empty response.body
  • Add render_views to the controller spec to render views and get the response
require "spec_helper"

describe WidgetsController do
  render_views

  describe "index" do
    it "renders the index template" do
      get :index
      response.should contain("Listing widgets")
    end

    it "renders the widgets/index template" do
      get :index
      response.should contain("Listing widgets")
    end
  end
end

HTTP request testing

  • Response of the request is found in response eg. response.body
  • Request can be debugged using request
  • Works for HTTParty

Easy pending

  • Add pending "Some message" will stop all execution in the example and mark it as pending. Useful if you need to stop the example from executing.

Testing before/after hooks in controller

  • Useful to test before_filter/after_filter hooks in controllers
require 'spec_helper'

describe ApplicationController do
  describe '#set_user_id_for_geolocation_js' do

    # Create an anonymous controller which inherits from ApplicationController
    controller do
      def index
        render :text => "Hello"
      end
    end

    let!(:user) { create(:user) }

    it 'sets the current user id in view if user is signed in' do
      sign_out user
      get :index
      assigns(:user_id).should be_nil

      sign_in user
      get :index
      assigns(:user_id).should == user.id
    end
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment