I'm building a Sinatra app currently that will be outputting JSON templates as part of an API. When testing with rails and the rspec-rails gem I was able to call:
response.should render_template('template-name')
However since I'm not using Rails I'm assuming this won't work. What's the alternative to use for Sinatra for testing the json output? Thanks!
There are some docs on using Rack Test with RSpec here, but this is how I set my stuff up. By wrapping the app in a module's class method it makes it a lot easier to run in the specs, then it's just a case of validating the response via last_response.body
(which is the short answer to your question).
# config.ru
require 'rubygems'
require "bundler/setup"
root = File.expand_path File.dirname(__FILE__)
require File.join( root , "./app/config.rb" )
# everything was moved into a separate module/file
# to make it easier to set up tests
map "/" do
run HelloWorld.app
end
# app/config.rb
require 'main'
module HelloWorld
def self.app
Rack::Builder.app do
# middleware setup here, cookies etc
run App
end
end
end
# app/main.rb
require 'sinatra/base'
module HelloWorld
class App < Sinatra::Base
get "/", :provides => :json do
{key: "value"}.to_json
end
end
end
# spec/spec_helper.rb
require 'rspec'
Spec_dir = File.expand_path( File.dirname __FILE__ )
require 'rack/test'
Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f|
require f
end
# spec/support/shared/all_routes.rb
require 'hello_world' # <-- your sinatra app
shared_context "All routes" do
include Rack::Test::Methods
let(:app){
HelloWorld.app
}
end
shared_examples_for "Any route" do
subject { last_response }
it { should be_ok }
end
# spec/hello_world_spec.rb
require 'spec_helper'
describe 'getting some JSON' do
include_context "All pages"
let(:expected) {
'{"key": "value"}'
}
before do
get '/', {}, {"HTTP_ACCEPT" => "application/json" }
end
it_should_behave_like "Any route"
subject { last_response.body }
it { should == expected }
end