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