Sessionography
This is a simple testing helper for Sinatra sessions. It was written because
having to use this sort of approach to test sessions made me sad.
Sessionography replaces Sinatra's session
helper with a reference to a
simple hash in a module variable, enabling session calls that maintain state
across requests without the complexity and limitations of trying to use
Rack::Session
with Rack::Test.
It will not help you sing better. It does not make omelettes. And if you're testing something that actually cares about how sessions get set (e.g., if you're working on Sinatra itself or a low-level Rack component) you won't want to use this. But most of us just want to get on with testing our apps.
Setting up
$ gem install sinatra-sessionography
(Or sudo gem install
if you're the last person on Earth who isn't using RVM yet.)
Then, in your test_helper.rb file or your spec_helper.rb file, just require sinatra/sessionography
. If you're using the Sinatra::Base style you'll also need to explicitly include the helper:
# spec_helper.rb
require 'myapp'
require 'sinatra/sessionography'
MyApp.helpers Sinatra::Sessionography
Testing Tips
Your app code can continue to call session[:whatever]
as it already does. It'll simply bypass any Rack::Session
middleware and set a hash in memory.
If you'd like to access that hash in your test cases, there are module methods available:
# This example is in RSpec, because that is how I roll.
describe HypotheticalApp do
before(:each) do
# Initialize the session every time. Here we simulate pre-existing state,
# but you could just as easily assign nil or call .clear
Sinatra::Sessionography.session = {:foo => 'bar', :too => 'tar'}
end
it "should do something to the session" do
post "/something", {:hey => :ho}
Sinatra::Sessionography.session['hey'].should == 'ho'
end
it "should pay attention to the session" do
Sinatra::Sessionography.session[:user] = User.find_by_name('Tina Fey')
get "/something"
last_response.body.should =~ /Tina Fey/
end
end
The session will of course persist across Sinatra requests. That's the point of a session. However, it will also persist between test cases, which is probably not what you want, so in your setup or teardown code you should always call Sinatra::Sessionography.session.clear
or else set it to nil or some other useful value.
Future Enhancements
I knocked this off quickly because I needed it (for Sinatra::Flash) but it'd be fairly easy to give it a few other features useful for testing:
- Multiple sessions scoped by name, for simulating interactions between different users;
- Logging or remembering of changes to session state, so that test cases can trace more complex interactions with the session over time;
- Generalization to a Rack::Session::Test (or perhaps Rack::MockSession) component for testing Rack applications outside of just Sinatra.
I don't need any of those today, so I'm not going to build them right away. But if you'd like to see them, feel free to leave an issue here and let me know. (Or just build it and contribute back, of course. The source, it is open like the sky.)
License
This project is licensed under the Don't Be a Dick License, version 0.2, and is copyright 2010 by Stephen Eley. See the LICENSE.markdown file or the DBAD License site for elaboration on not being a dick.