Testing web services with ActiveResource
ActiveResource can be a useful tool for abstracting away low level HTTP or data marshaling details when testing web services with an XML schema and URI patterns which respect the Rails protocol for REST.
Here's a possible implementation for use in tests that exercise a service from the outside, a sort of black box web service testing approach, if you'd like.
def resource(name) class_name = name.to_s.camelize return class_name.constantize if Object.const_defined?(class_name.intern) rsrc = Class.new(ActiveResource::Base) do self.site = "http://localhost:4001/api" self.element_name = name.to_s end Object.const_set(class_name.intern, rsrc) end
Let's imagine an API call to
http://localhost:4001/api/categories.xml
which returns a list of product categories with their respective subcategories. Following is a potential response to a
GET
request to the afore mentioned URI.
<?xml version="1.0" encoding="UTF-8"?> <categories type="array"> <category> <id type="integer">3</id> <name>Music</name> <subcategories type="array"> <subcategory type="Category"> <id type="integer">4</id> <name>Rock</name> </subcategory> <subcategory type="Category"> <id type="integer">5</id> <name>Metal</name> </subcategory> </subcategories> </category> </categories>
Invoking
resource :category
in the test will provide a
Category
class.
Category
is an
ActiveResource
child which can be used to exercise the
/categories
end point of the API.
class ApiTest < Test::Unit::TestCase resource :category def test_categories categories = Category.find(:all) assert_equal(1, categories.size) assert_equal("Music", categories.first.name) end def test_subcategories subcategories = Category.find(:all).first.subcategories assert_equal(2, subcategories.size) assert_equal("Metal", subcategories[1].name) end def test_category_creation Category.create(:name => "Hacking") assert_equal(3, Category.find(:all).size) end end