Testing responds_to

Posted by Rob Kaufman
on May 20, 07

I was having an issue after adding some RJS on one of my apps. After looking at this page I was surprised that respond_to order is very much order dependent, which only really matters in your test cases. Then I found a post on Singlecell that 'solves' this testing problem. It wasn't quite a 'whole' solution, but it did handle POST and GET. I've expanded it to the following:

#Much like the #get and #post methods we're all so fond of, but with an additional 'type'
# argument which may be any type supported by
#response_type_to_mime_type (currently :js, :html or :xml)

["get", "post", "put", "delete"].each do |kind|
  code = <<CODE
    def #{kind}_with(type, action,  params={}, headers={})
      accept type
      #{kind} action, params, headers
      # Reset the request to accept HTML after
      accept :html
    end
  CODE
  eval code
end

# Helps out with response testing, by letting to assert that the most recently-made request responded with one of
# :html, :js or :xml
def assert_responded_with(s)
  assert_match @response.headers['Content-Type'], "#{response_type_to_mime_type(s)}; charset=utf-8", 
               "Response did not match expected. Expected #{s} but was #{@response.headers['Content-Type']}"
end

# Switches the request object's Accept header to a new type, one of :html, :js or :xml
def accept(type)
  @request.accept = response_type_to_mime_type(type)
end

def response_type_to_mime_type(s)
  case s
    when :html
      'text/html'
  when :js
   'text/javascript'
  when :xml
    'application/xml'
  else
    raise ArgumentError("Unsupported content type in response_to_mime_type: don't know how to turn :#{s.to_s} into MIME type")
  end
end

now you can do

post_with
get__with
put_with
delete__with

and couple that with

assert_responded_with
Comments

Leave a response

Comment