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