Tue 14 Jul 2020
Reading time: (~ mins)
Rspec is one of the libraries that really shows off how fun ruby is. An elegant DSL for testing that is a joy to use. Unfortunately user sessions can be a pain to test so I'll show you how to easily make specs for flash messages in your Rack apps.
We have a simple Sinatra app with three routes. /flash redirects and sets a flash message, which is what we want to verify with our tests
# my_app.rb
require 'sinatra'
require 'rack-flash'
class MyApp < Sinatra::Base
enable :sessions # need this for flash to work
use Rack::Flash
get '/' do
"Hello World. <a href='/flash'>Test Rack::Flash</a>"
end
get '/flash' do
flash[:success] = 'Flashed!' # set the flash message we want
redirect '/flash/message'
end
get '/flash/message' do
"Here is your flash message: #{flash[:success]}" # display flash
end
end
Before writing the tests we setup a spec helper to load our testing tools and environment, which includes RSpec and Rack::Test:
# spec/spec_helper.rb
ENV['APP_ENV'] = 'test'
require_relative '../my_app.rb'
require 'rspec'
require 'rack/test'
module RSpecMixin
include Rack::Test::Methods # loads in rack/test methods
def app; described_class; end # tells rspec where our app is
def flash # the secret sauce
response
last_request.env['x-rack.flash']
end
end
RSpec.configure do |config|
config.include RSpecMixin # include our settings into RSpec
end
# spec/my_app_spec.rb
require 'spec_helper'
describe MyApp do
context '/' do
let!(:response) { get '/' } # Rack::Test let us do this
it "says hello" do
expect(last_response.body).to include 'Hello World'
end
end
context '/flash' do
let(:response) { get '/flash' }
it 'sets flash success' do
expect(flash[:success]).to eq 'Flashed!' # TADA!
end
end
context '/flash/success' do
let(:response) { get '/flash/message' }
it 'does not show flash when accessed directly' do
expect(flash[:success]).to be_nil # further testing
end
end
end
And for completeness here is the Gemfile and config.ru for this little project:
# Gemfile source 'https://rubygems.org' gem 'sinatra' gem 'rack-flash3' group :test do gem 'rack-test' gem 'rspec' end # config.ru require_relative 'my_app.rb' run MyApp
Hopefully this helps you with your testing. Seems like a lot of people were scratching their heads about it when I tried to google solutions.
Enjoy!