ShamRack
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'
ShamRack.at("www.greetings.com") do |env|
["200 OK", { "Content-type" => "text/plain" }, ["Hello, world!"]]
end
require 'open-uri'
open("http://www.greetings.com/").read #=> "Hello, world!"
Sinatra integration
ShamRack.at("sinatra.xyz").sinatra do
get "/hello/:subject" do
"Hello, #{params[:subject]}"
end
end
open("http://sinatra.xyz/hello/stranger").read #=> "Hello, stranger"
Rackup support
ShamRack.at("rackup.xyz").rackup do
use Some::Middleware
use Some::Other::Middleware
run MyApp.new
end
Any old Rack app
ShamRack.at("google.com").mount(my_google_stub)
General-purpose stubbing
@stub_app = ShamRack.at("stubbed.com").stub
@stub_app.register_resource("/greeting", "Hello, world!", "text/plain")
open("http://stubbed.com/greeting").read #=> "Hello, world!"
@stub_app.last_request.path #=> "/greeting"
On a specific port
ShamRack.at("example.com", 8080) do |env|
["200 OK", { "Content-type" => "text/plain" }, ["Hello, world!"]]
end
Or, just use Sinatra, as described above ... it's almost as succinct, and heaps more powerful.
Avoiding (accidental) real network connections
ShamRack.prevent_network_connections
When you're done testing
ShamRack.reset
open("http://stubbed.com/greeting").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("http://www.greetings.com/")
Net::HTTP.get_response(uri).body #=> "Hello, world!"
require 'open-uri'
open("http://www.greetings.com/").read #=> "Hello, world!"
require 'restclient'
RestClient.get("http://www.greetings.com/").to_s #=> "Hello, world!"
require 'mechanize'
Mechanize.new.get("http://www.greetings.com/").body #=> "Hello, world!"
Patron (experimental)
We've recently added support for Patron:
require 'sham_rack/patron'
patron = Patron::Session.new
patron.get("http://www.greetings.com/").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.