run Rack applications in-process, without a server
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
benchmark Compare performance of ShamRack vs running a Rack app in a separate p… Jun 27, 2009
lib Remove "ShamRack.mount". Nov 19, 2015
spec Remove "ShamRack.mount". Nov 19, 2015
.rspec Create a ".rspec" file. Apr 4, 2013
.travis.yml Avoid rack-2.0 for now. Jan 6, 2017 First release in years!! Jan 6, 2017
Gemfile Update rspec. Jan 6, 2017
LICENSE Specify a license (the MIT license). Apr 29, 2013 Add support for "ShamRack.allow_network_connections". Nov 19, 2015
Rakefile Update RSpec, and drop RR in favour of rspec-mocks. Mar 7, 2015
sham_rack.gemspec Add dependency on Rack. Link Gemfile to gemspec. Restrict RSpec version. Dec 22, 2010


Gem Version Build Status

ShamRack plumbs HTTP requests into Rack.

What's it for, again?

Well, it makes it easy to stub out external (HTTP) services, which is handy in development and testing environments, or when you want to test your HTTP client code.

You can also use it to test your Rack application (or Sinatra, or Rails, or Merb) using a variety of HTTP client libraries, to check interoperability. For instance, you could test your app using:

all without having to boot it in a server.

Installing it

gem install sham_rack

Using it

A simple inline application

require 'sham_rack'"") do |env|
  ["200 OK", { "Content-type" => "text/plain" }, ["Hello, world!"]]

require 'open-uri'
open("").read            #=> "Hello, world!"

Sinatra integration"").sinatra do
  get "/hello/:subject" do
    "Hello, #{params[:subject]}"

open("").read  #=> "Hello, stranger"

Rackup support"").rackup do
  use Some::Middleware
  use Some::Other::Middleware

Any old Rack app"").mount(my_google_stub)

General-purpose stubbing

@stub_app ="").stub
@stub_app.register_resource("/greeting", "Hello, world!", "text/plain")

open("").read       #=> "Hello, world!"
@stub_app.last_request.path                    #=> "/greeting"

Or, just use Sinatra, as described above ... it's almost as succinct, and heaps more powerful.

Avoiding (accidental) real network connections


When you're done testing


open("").read       #=> OpenURI::HTTPError

Supported HTTP client libraries

Net::HTTP and friends

ShamRack supports requests made using Net::HTTP, or any of the numerous APIs built on top of it:

uri = URI.parse("")
Net::HTTP.get_response(uri).body                      #=> "Hello, world!"

require 'open-uri'
open("").read                #=> "Hello, world!"

require 'restclient'
RestClient.get("").to_s      #=> "Hello, world!"

require 'mechanize'"").body   #=> "Hello, world!"

Patron (experimental)

We've recently added support for Patron:

require 'sham_rack/patron'

patron =
patron.get("").body          #=> "Hello, world!"

What's the catch?

  • Your Rack request-handling code runs in the same Ruby VM, in fact the same Thread, as your request.

Thanks to

  • Blaine Cook for FakeWeb, which was an inspiration for ShamRack.
  • Perryn Fowler for his efforts plumbing Net::HTTP into ActionController::TestProcess.
  • Christian Neukirchen et al for the chewy goodness that is Rack.