Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Way to Test Rails REST XML API?

I want to test the REST api on my Rails site. What is the easiest/best way to do this with the rails testing framework? I'm only doing the standard resourceful stuff, so I am wondering in particular, since this is so bog standard, if there is any automagical way to test this stuff.

like image 405
jcnnghm Avatar asked Apr 15 '09 16:04

jcnnghm


1 Answers

I rolled my own solution to this and thought it would be helpful. I wrote a module that uses the json, curb, and addressable gems to send GET, PUT, POST, and DELETE requests to localhost:3000. It can request either XML (as the original question asked for) or json. It returns the response body as a Hash. It is mostly a wrapper around the curb gem, which I think has horrendous syntax.

Note that I am automatically loading my api_key. This can be disabled by passing :api_key => false or broken using api_key => "wrong". You might want to leave this out or modify it to fit your authentication scheme.

Here's the module:

module ApiTesting
  # requres the json, curb, and addressable gems

  require "addressable/uri"

  def api_call(path, verb, query_hash={}, options={})
    options.reverse_merge! :api_key => "abc1234", :format => "xml"
    query_hash.reverse_merge!({:api_key => options["api_key"]}) if options[:api_key]
    query = to_query_string(query_hash)
    full_path = "http://localhost:3000/#{path}.#{options[:format]}?#{query}"
    response = case verb
      when :get
        Curl::Easy.perform(full_path)
      when :post
        Curl::Easy.http_post("http://localhost:3000/#{path}.#{options[:format]}", query)
      when :put
        Curl::Easy.http_put(full_path, nil)
      when :delete
        Curl::Easy.http_delete(full_path)
    end
    case options[:format]
      when "xml"
        Hash.from_xml(response.body_str)
      when "json"
        JSON.parse(response.body_str)
    end
  end

  private

  def to_query_string(val)
    uri = Addressable::URI.new
    uri.query_values = val
    uri.query
  end

end

And here are some simple examples: Requesting resource attributes with GET:

    api_call("calls/41", :get)

Creating resources with POST:

    api_call("people", :post, {:person => {:first => "Robert", :last => "Smith" } })

Updating resources with PUT:

    api_call("people/21", :put, {:person => { :first => "Bob" } })

Deleting resources with DELETE:

    api_call("calls/41", :delete)

Turning off automatic insertion of api_key:

    api_call("calls/41", :get, {}, {:api_key => false})

Use the wrong api_key:

    api_call("calls/41", :get, {}, {:api_key => "wrong"})

Use as json (default is xml):

    api_call("calls/41", :get, {}, {:format => "json"})
like image 173
muirbot Avatar answered Sep 19 '22 14:09

muirbot