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 endAnd 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!