How to Test a Sinatra App with Rspec

I’ve been working with Sinatra for the past few weeks and finally figured out how to test Sinatra routes with Rspec. I also realized there aren’t nearly as many blog articles written on this topic as usual so it’s my duty to contribute to the world with my newfound knowledge.

Once you figure out the syntax, tesing Sinatra routes is very similar to other rspec tests. Here’s the basic process:
1) Require the correct libraries for testing Sinatra
2) Call the routes
3) Look at the last response to see if what you expect to appear in the browser does appear OR look at the last request to see if the correct route was requested.

Preview Sinatra App

Let’s check out the example Sinatra App that we’ll be testing:

sinatra_app.rb

require 'sinatra/base'

class SinatraApp < Sinatra::Base
    get '/' do
      erb :home
    end

    get '/about' do
	erb :about
    end

    get '/welcome' do
        if params[:user].nil?
           redirect '/'
        else
           @user = params[:user]
	   erb :welcome_user
        end
    end
end

Set up Sinatra Tests

At the top of our Rspec tests, we need to require some libraries and include a module, like so:

sinatra_app_spec.rb

require 'sinatra_app.rb'
require 'rack/test'

describe 'Sinatra App' do
  include Rack::Test::Methods

  def app
    SinatraApp.new
  end
end

...

Calling routes

In order to test each route you can simply call it like you’re calling a method.

...

it "displays home page" do 
  get '/'
end

it "displays about page" do 
  get '/about'
end

it "displays welcome page if a user exists" do 
  get '/welcome'
end

it "displays home page if there is no user" do 
  get '/welcome'
end

Make assertions with Last Reponse

Let’s assume that:

  • home page just says “Hello world!”
  • about page just says “Meet the team:” followed by long descriptions of each team member
  • welcome page says “Hey, (user). Thanks for coming back!”

To check to see if the correct page displays when you call a route, you check to see that the body of the response has the unique text you are looking for in it.

it "displays home page" do 
  get '/'

  expect(last_response.body).to include("Hello world!")
end

it "displays about page" do 
  get '/about'

  expect(last_response.body).to include("Meet the team:")
end

Testing Params

I’m sure you noticed that we are going to have to check to see if the param[:user] is passed through to the welcome page in order to know which page should be displayed. If a user exists, we want to welcome them. If not, we want to send them back to the home page.

Here’s how you add params in testing:

it "displays welcome page if a user exists" do 
  get '/welcome', :user => "Laura"

  expect(last_response.body).to include("Hey, Laura. Thanks for coming back!")
end

Testing Redirects

Last but not least, we need to redirect to the homepage if a user does not exist. You test for redirects by checking the last response, then you follow the last response and check the path, like so:

it "displays home page if there is no user" do 
  get '/welcome', :user => nil

  expect(last_response.redirect?).to be_true
  follow_redirect!
  expect(last_request.path).to eq('/')
end

Wrapping Up

So there you have it — a few different ways to test a Sinatra App. Just so you can see it all together, here’s what the final test class looks like.

sinatra_app_spec.rb

require 'sinatra_app.rb'
require 'rack/test'

describe 'Sinatra App' do
  include Rack::Test::Methods

  def app
    SinatraApp.new
  end

  it "displays home page" do 
    get '/'

    expect(last_response.body).to include("Hello world!")
  end

  it "displays about page" do 
    get '/about'

    expect(last_response.body).to include("Meet the team:")
  end

  it "displays welcome page if a user exists" do 
    get '/welcome', :user => "Laura"

    expect(last_response.body).to include("Hey, Laura. Thanks for coming back!")
  end

  it "displays home page if there is no user" do 
    get '/welcome', :user => nil

    expect(last_response.redirect?).to be_true
    follow_redirect!
    expect(last_request.path).to eq('/')
  end
end

Leave a Reply

Your email address will not be published. Required fields are marked *