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