Lets say you just extracted some part of Rails application to a smaller, more contained Sinatra app. Now, you mounted it on your rails router and you're ready to add a new feature. You write some specs with Rspec. But the errors you get aren't quite what you were expecting.
Lets say you have a spec file called
app_spec.rb that looks like this:
require 'spec_helper' describe '/app' do it 'returns a 200' do get '/app' expect(last_response.status).to eq 200 end end
Your Sinatra app is a single file in your
sinatra_app.rb with this code:
class SinatraApp < Sinatra::Base get '/app' do raise 'bug' status 200 end end
And, don't forget, you mounted the app on your
require './lib/sinatra_app' mount SinatraApp, at: '/'
There's clearly a bug on the Sinatra app. When you call the
/app endpoint, it's gonna raise an exception before it sets the status to 200.
When you run your specs, this is what you get:
rspec F Failures: 1) /app returns a 200 Failure/Error: expect(last_response.status).to eq 200 expected: 200 got: 500 (compared using ==) # ./spec/app_spec.rb:6:in `block (2 levels) in <top (required)>' Finished in 0.38244 seconds (files took 2.54 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/app_spec.rb:4 # /app returns a 200
Well, this isn't too bad. It tells you that you were expecting a 200 but you got a 500 instead. But it could be a lot better. Your code is raising an exception, and it would be much better if the test output gave you that information with a stack trace.
The reason why it's not showing you the exception, is because Sinatra is catching it and giving it a nice output before returning the control back to Rails. This is done by a piece of middleware called
Now, if we look at Sinatra's source code, it's easy to find that this middleware is only mounted by default in development mode. But we're in test mode. What went wrong?
Well, the answer is quite simple. Sinatra looks at an environment variable called
RACK_ENV to determine which environment you're on. Rails, uses
RAILS_ENV. When you run your specs, the framework is setting the later but not the former. So, all you have to you is go to your
spec_helper.rb and add the following line:
ENV['RACK_ENV'] ||= 'test'
Run your specs again and you get:
rspec F Failures: 1) /app returns a 200 Failure/Error: get '/app' RuntimeError: bug # ./lib/sinatra_app.rb:3:in `block in <class:SinatraApp>' # /Users/andre/.rvm/gems/ruby-2.1.1/gems/sinatra-1.4.5/lib/sinatra/base.rb:1603:in `call' (...) # /Users/andre/.rvm/gems/ruby-2.1.1/gems/rack-test-0.6.3/lib/rack/test.rb:58:in `get' # ./spec/app_spec.rb:5:in `block (2 levels) in <top (required)>' Finished in 0.8245 seconds (files took 2.55 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/app_spec.rb:4 # /app returns a 200
Slightly more verbose but gives you all the information you need to dive in your code and fix that bug.