A few weeks ago i was chatting with Ryan Bigg about one of his projects, and he was contemplating about the fact he couldn’t find a decent way to test a remote XMLRPC service handling in that application.
Testing remote service calls like a boss is achieved by using FakeWeb which is pretty awesome when you work in front of a REST web service of something like that, but it does have a really big -1 on it: It binds a mocked response to a specific url, and you can’t add more responses for that url based on parameters.
Meaning, basically, that if you want for example to test a web service that requires POST requests to a specific url, FakeWeb just won’t cut it.
So basically, Ryan suggested an idea that seemed nice at the moment: add a Rails metal Rack app to handle those requests.
Awesome idea, but a few setbacks:
- If you don’t want that application to run on other environments, you’ll have to scope the behavior to the test environment only, simple? yeah. but personally i don’t like having
if Rails.env == "test"in my code.
- Since we are trying to mock a webservice, we’ll have to add different handlers in that metal application which can lead to a long, ugly, conditional and eye-ripping unmaintainable code.
So there I thought, why not just initiate a Sinatra application as part of your tests, and easily manage that sinatra as the mocked web service? WIN.
I created the SinatraFakeWebService gem that provides a simple interface to instantiate that Sinatra application and to manage the mocked webservice interface.
Install the gem:
sudo gem install sinatra_fake_webservice
If you use bundler or such:
gem 'sinatra_fake_webservice', :group => 'test'
should do it.
test_helper.rb or the Cucumber/rSpec equivalent:
If this would be proven as useful, i’ll probably add a better DSL for the interaction other than the ugly Net::HTTP all over.