Rails Functional Testing of mime types other than HTML (XML, JSON etc)

I noticed something interesting these days. Even though most Rails websites boasts the benefits of Test Driven Development, most examples they give us don’t test the whole app functionality. 

How come? Well, REST was the word of the day, it is now deep inside our brains, right? But have you ever seen an example test of the XML output of Rails? Surely not. Every guide, tutorial and example shows only how to test for the default output, which is HTML. 

So what? That ought to be easy, right? Just add :format after the get, post, put or delete function and you will be fine, you must think. Well, I have been working on a project and had to test if the Atom Feed would work ok. I must say it was one of the most frustrating tests I have ever written. 

Turns out that, even though you can do something like this:


formatted_posts_url(:format => :atom)

you CAN’T do that on testes:

get :index, :format => :atom

 

You know why? Because, even though you CAN use symbols (:atom) on your code, you CAN’T use on tests FOR THE FORMAT. Let’s rephrase it: You can use symbols on tests when specifying the action, the parameters and everything else BUT NOT THE FORMAT of the request. So the code above will give you a mysterious HTTP 406 Error Code.

So, to prevent you from loosing a full day where you felt productive, like I did, the following code will work:

get :index, :format => "atom"

Best!

About these ads

~ by Dante Regis on December 16, 2008.

15 Responses to “Rails Functional Testing of mime types other than HTML (XML, JSON etc)”

  1. Thanks for this…or else I would have spent the nite just watching TV lol.

  2. Hehe, you said testes.

    But anyway, thanks for this note — I was having the exact same problem.

  3. thanks for the hint. you saved me a day indeed :)

  4. Thanks a lot for writing this post! Saved me a lot of time. I’m using this with the xml_http_request method, which was deceiving since I assumed it would send a request for xml. But no, xml_http_request requests the default html format… Oh well, it’s just testing, right? /s

  5. Good catch, another day saved here.

  6. Did I hear somebody say type safety didn’t matter?

    This is the kind of thing that makes me crave Java and Scala.

  7. Saved me hours and hours of pain. Thanks!

  8. post :foo, :format => ‘xml’
    # request.format in controller correctly returns application/xml

    post :foo, :format => ‘json’
    # request.format STILL returns xml, which is apparently cached (!!)

    WTF – HATE RAILS. It breaks EVERY time you try to do anything clever.

  9. In this case I needed to re-run a basic setup method re-initializing @request as @request = ActionController::TestRequest.new. This is because AbstractRequest uses ||= when analyzing the mime type and functional tests inexplicably re-use the request object, making testing multiple types of calls impossible in one test.

  10. Thanks for this. I would have figured it out eventually but you saved me at least a few hours of pulling my hair out.

  11. Thank god for blogging and googling. Problem solved. Thank you.

  12. +1

  13. OMG I was beating myself over the head with this one for months!!! Thank you Thank you!!! Thank Gods for blogs ’cause #RoR usually just looks at you funny and StackOverflow > /dev/null

    You rock!

  14. Thanks, man. This is the only mention I have seen of this anywhere! This was driving me nuts for over an hour.

  15. ditto. I imaginge you’ll be getting thanked for this for a few more years to come :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: