title | layout | id |
---|---|---|
Testing Sinatra with Rack::Test |
default |
testing |
NOTE: Sinatra's built-in test framework has been deprecated in favor of Rack::Test as of version 0.9.2. This document describes testing with Rack::Test.
All examples in the following sections assume that Test::Unit
is being
used in an attempt to be as general as possible. See the Test Framework
Examples for information on using the test helpers in
other testing environments.
The following example app is used to illustrate testing features. This is
assumed to be in a file named hello_world.rb
:
require 'sinatra'
get '/' do
"Hello World #{params[:name]}".strip
end
The Rack::Test::Methods
module includes a variety of helper methods for
simulating requests against an application and asserting expectations about
the response. It's typically included directly within the test context and
makes a few helper methods and attributes available.
The following is a simple example that ensures the hello world app functions properly:
require 'hello_world'
require 'test/unit'
require 'rack/test'
set :environment, :test
class HelloWorldTest < Test::Unit::TestCase
include Rack::Test::Methods
def app
Sinatra::Application
end
def test_it_says_hello_world
get '/'
assert last_response.ok?
assert_equal 'Hello World', last_response.body
end
def test_it_says_hello_to_a_person
get '/', :name => 'Simon'
assert last_response.body.include?('Simon')
end
end
For a variety of reasons you may not want to include Rack::Test::Methods
into your own classes. Rack::Test
supports this style of testing as well,
here is the above example without using Mixin.
require 'hello_world'
require 'test/unit'
require 'rack/test'
set :environment, :test
class HelloWorldTest < Test::Unit::TestCase
def test_it_says_hello_world
browser = Rack::Test::Session.new(Rack::MockSession.new(Sinatra::Application))
browser.get '/'
assert browser.last_response.ok?
assert_equal 'Hello World', browser.last_response.body
end
def test_it_says_hello_to_a_person
browser = Rack::Test::Session.new(Rack::MockSession.new(Sinatra::Application))
browser.get '/', :name => 'Simon'
assert browser.last_response.body.include?('Simon')
end
end
The get
, put
, post
, delete
, and head
methods simulate the
respective type of request on the application. Tests typically begin with
a call to one of these methods followed by one or more assertions against
the resulting response.
All mock request methods have the same argument signature:
get '/path', params={}, rack_env={}
-
/path
is the request path and may optionally include a query string. -
params
is a Hash of query/post parameters, a String request body, ornil
. -
rack_env
is a Hash of Rack environment values. This can be used to set request headers and other request related information, such as session data. See the Rack SPEC for more information on possible key/values.
Once a request method has been invoked, the following attributes are available for making assertions:
-
app
- The Sinatra application class that handled the mock request. -
last_request
- TheRack::MockRequest
used to generate the request. -
last_response
- ARack::MockResponse
instance with information on the response generated by the application.
Assertions are typically made against the last_response
object.
Consider the following examples:
def test_it_says_hello_world
get '/'
assert last_response.ok?
assert_equal 'Hello World'.length.to_s, last_response.headers['Content-Length']
assert_equal 'Hello World', last_response.body
end
The Rack::Test
mock request methods send requests to the return value of
a method named app
.
If you're testing a modular application that has multiple Sinatra::Base
subclasses, simply set the app
method to return your particular class.
def app
MySinatraApp
end
If you're using a classic style Sinatra application, then you need to return an
instance of Sinatra::Application
.
def app
Sinatra::Application
end
If you'd like the Rack::Test
methods to be available to all test cases
without having to include it each time, you can include the Rack::Test
module in the Test::Unit::TestCase
class:
require 'test/unit'
require 'rack/test'
class Test::Unit::TestCase
include Rack::Test::Methods
end
Now all TestCase
subclasses will automatically have Rack::Test
available to them.
As of version 0.9.1
, Sinatra no longer provides testing framework-specific
helpers. Those found in sinatra/test/*.rb
are deprecated and will be
removed in Sinatra 1.0
.
Sinatra can be tested under plain RSpec. The Rack::Test
module should be
included within the describe
block:
require 'hello_world' # <-- your sinatra app
require 'spec'
require 'rack/test'
set :environment, :test
describe 'The HelloWorld App' do
include Rack::Test::Methods
def app
Sinatra::Application
end
it "says hello" do
get '/'
last_response.should be_ok
last_response.body.should == 'Hello World'
end
end
Make Rack::Test
available to all spec contexts by including it via
Spec::Runner
:
require 'spec'
require 'rack/test'
Spec::Runner.configure do |conf|
conf.include Rack::Test::Methods
end
Testing with Bacon is similar to test/unit
and RSpec:
require 'hello_world' # <-- your sinatra app
require 'bacon'
require 'rack/test'
set :environment, :test
describe 'The HelloWorld App' do
include Rack::Test::Methods
def app
Sinatra::Application
end
it "says hello" do
get '/'
last_response.should.be.ok
last_response.body.should.equal 'Hello World'
end
end
Make Rack::Test
available to all spec contexts by including it in
Bacon::Context
:
class Bacon::Context
include Rack::Test::Methods
end
The Rack::Test
module should be included within the context of the
describe
block:
require 'hello_world' # <-- your sinatra app
require 'test/spec'
require 'rack/test'
set :environment, :test
describe 'The HelloWorld App' do
include Rack::Test::Methods
def app
Sinatra::Application
end
it "says hello" do
get '/'
last_response.should.be.ok
last_response.body.should.equal 'Hello World'
end
end
Make Rack::Test
available to all spec contexts by including it in
Test::Unit::TestCase
:
require 'test/spec'
require 'rack/test'
Test::Unit::TestCase.send :include, Rack::Test::Methods
See the source for Rack::Test for
more information on get
, post
, put
, delete
and friends.