<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>DogBiscuit</title>
    <description>... mmm, crunchy!</description>
    <link>http://dogbiscuit.org/mdub/weblog</link>
    <language>en-us</language>
    <generator>EvenYetAnotherWeblog</generator>
    <item>
      <title>Introducing ShamRack</title>
      <guid>http://dogbiscuit.org/mdub/weblog/Tech/Projects/ShamRack</guid>
      <pubDate>Fri, 03 Jul 2009 15:50:00 +1000</pubDate>
      <description><![CDATA[<p>
The system I'm currently working on integrates with several external systems, over HTTP, using simple (RESTish) web-services.  I really don't want to involve those external systems while testing my own, though; I want to stub 'em out.
</p>
<p>
My first attempt involved stubbing out HTTP calls using my mocking framework of choice.  I'm using <a href='http://rest-client.heroku.com'>RestClient</a>, which I like a lot, and stubbing out RestClient API calls worked quite well.  It kept on working quite well for several hours, until I decided to refactor a little, using RestClient in a slightly differently way, at which point it broke completely.  Bother.  I really don't like having tests coupled to implementation details, so went searching for another way.
</p>
<p>
<a href='http://fakeweb.rubyforge.org'>FakeWeb</a> looked pretty good, in that it stubs things out at the Net::HTTP layer, which I'm unlikely to refactor out of the picture.  In the end, though, it's not really what I wanted. I wanted to be able to do things like:
</p>
<ul>
<li>
verify the body (and mime-type) of a POST/PUT request
</li>
<li>
dynamically generate responses, based on some aspect of the request (e.g. query parameters) 
</li>
</ul>
<p>
In short, I wanted a <a href='http://xunitpatterns.com/Fake%20Object.html'>Fake Object</a>, rather than a simple stub.
</p>
<p>
It occurred to me around about then that we already have plenty of tools for describing the behaviour of web-applications: they're called web-application frameworks!  Many of them are too heavy-weight for my purposes, but <a href='http://www.sinatrarb.com/'>Sinatra</a> is nicely minimal.  So, 60 lines of Ruby code later, I had a little web-app that mimicked one of those external web-services sufficiently for my testing.  Win!
</p>
<p>
But waitaminut.  I really don't want to have to start a separate process running my fake web-service, and talk to it using HTTP.  That's going to be slow: network I/O isn't cheap.  Isn't there some way I can use something like Sinatra but still keep everything in-process?
</p>
<p>
There is now.  <a href='http://github.com/mdub/sham_rack'>ShamRack</a> plumbs Net::HTTP directly into applications built to run on <a href='http://rack.rubyforge.org/'>Rack</a>.  Which includes all Sinatra apps, as well as Rails, Merb, etc.
</p>
<p>
<div align="center">
<img src="/mdub/images/ShamRack.png" />
</div>
</p>
<p>
Using ShamRack, I avoid the network traffic, making the tests a whole lot faster (about 25 times faster, in my case).  Plus, I avoid the complication of having to start and stop an external web-server.  Finally, because my fake web-service app is in-process, I get a handy back-channel I can use to setup or inspect it's state during tests.
</p>
<p>
If you find ShamRack handy, or have ideas about how it could improve, let me know!
</p>
]]></description>
    </item>
  </channel>
</rss>
