I’ve recently started to add XML support to a Rails application, meaning that the application provides data in XML format, if the request asks for it, and it understands XML data on create or update.
To keep the application as well as myself sane, I’ve written a test that ensures the round trip of getting XML and updating an object by sending XML works. This is only a very basic test and there surely is more that can and should be tested.
class XmlRoundtripTest < ActionController::IntegrationTest
RESOURCES = [
:people, :things
]
fixtures :stuff, *RESOURCES
def self.assert_roundtrippability_for(*resources)
resources.each do |resource|
define_method("test_xml_roundtrip_for_#{resource}") do
@user = user
@user.logs_in
xml = @user.gets_xml(resource)
@user.changes_object_name!(xml)
old_version = @user.extracts_lock_version(xml)
@user.sends_xml(xml, resource)
# Make sure that the resource was really updated
new_version = @user.extracts_lock_version(@user.gets_xml(resource))
assert_equal(old_version + 1, new_version)
end
end
end
assert_roundtrippability_for *RESOURCES
def user
open_session do |user|
def user.gets_xml(resources, id = 1)
get "/#{resources}/#{id}.xml"
assert_response :success
@response.body
end
def user.sends_xml(xml, resources, id = 1)
put "/#{resources}/#{id}.xml", xml, :content_type => 'application/xml'
assert_response :success
@response.body
end
def user.changes_object_name!(xml)
# arbitrarily change an attribute we know is there
xml.gsub!(%r{<name>(.*?)</name>}, '<name>X\1Y</name>')
end
def user.extracts_lock_version(xml)
xml =~ %r{<lock-version>(\d+)</lock-version>}
$1.to_i
end
end
end
end




