Testing Warden-Based Sinatra Apps

1 minute read Published:

I recently integrated Warden into a web service I’ve been building with Sinatra. Unfortunately doing so completely broke some of my tests. I spent a while trying to figure out how to stub out the Warden object before I discovered that Warden already provides support for testing. Awesome. While I could load my config.ru in the test, there are other things in there that I’d rather not deal with while testing. I came up with the following approach, which lets me more or less test the web service in isolation.

require 'rack/test' require 'sinatra' require 'rspec' require 'warden' # model class User attr_reader :id attr_reader :name def initialize(name) @id = 1 # please don't really do this @name = name end end # modular sinatra app class Greeter < Sinatra::Base get '/' do "Hello, #{request.env['warden'].user.name}" end end # tests describe Greeter do include Rack::Test::Methods include Warden::Test::Helpers after(:each) do Warden.test_reset! end def app Rack::Builder.new do # these serialization methods don't do anything in this example, # but they could be necessary depending on the app you're testing Warden::Manager.serialize_into_session { |user| user.id } Warden::Manager.serialize_from_session { |id| User.get(id) } # your session middleware needs to come before warden use Rack::Session::Cookie use Warden::Manager run Greeter end end it 'says hi to me' do login_as User.new('Marc') get '/' last_response.body.should == 'Hello, Marc' end end

This is basically just an inline rackup file. Where you would normally return just the Sinatra app, you instead put together the bits that you need to exercise the code under test.