Monday, January 18, 2010

Testing ActiveResource classes with Fakeweb and Shoulda

It is not as simple to write unit tests for Active Resource models as they often depend on external web service. It is not mostly possible to get or create a Sandbox web service for unit testing your Active Resource classes. In such scenario you need a way to mock how the RESTful web service would behave in production.

I initially tried to use HttpMock which is used to test Active Resource framework within Rails. It is undocumented and you need to dig through web and Rails documentation it self to see how it works. Recently I came across excellent FakeWeb gem and ever since that I have been hooked on it. I am impressed by simplicity with which we I can mock RESTFul Rails web services.

Here is how I use Test::Unit and Shoulda with Rails to Mock RESTful web services for Active Resource classes. I am using XML based web services so I needed sample XML responses that Mock service should return. I create XML files containing those sample responses and store them under test/fixtures folder. After that I edited test_helper.rb file in test folder to have this utility method which loads sample responses from XML files located in fixtures folder.

After this lets jump on to unit test that we are going to write for our Active Resource class. Lets say we are testing an Active Resource class named User. Here is how I write unit test with FakeWeb and Shoulda gem.

First I am requiring both FakeWeb and Shoulda a gem. I would also add these gems to config/environments/test.rb as required gem for test environment.

After requiring these two gems I would disable real HTTP connections so not to mix real Web services calls with mock RESTful Web services by setting allow_net_connect property of FakeWeb class to false. Similarly in teardown method I would re-enable net HTTP connections by setting allow_net_connect property to true.

Now I am going to write actual test using FakeWeb within Shoulda context blocks.

Here within the context block I am setting up url to register as GET request to return response that is contained in XML file. After that a simple test checks the returned response object with some assertions. This shows how easy it is to create mock RESTful web services with FakeWeb and test your Active Resource classes with RSpec or  Test::Unit