Sunday, August 15, 2010

Helper Testing in Rails 3

This post shows how to test both simple and complicated testers in Rails 3. The method outlined here should work in Rails 2.3 as well, but it might not be the best method.

The skeleton helper testcase class generated by Rails 3 inherits from ActionView::TestCase. Simple helpers can be tested by comparing their return value with a golden string. For more complex helpers, use render :text to fill the view state with the helper return value, then use assert_select. assert_tag doesn't work.

Simple Helpers
Helpers that produce a single tag, or a string, are probably best tested simply by comparing their output with an expected value. Helpers can be called directly from the test class, as inheriting from ActionView::TestCase will set up an appropriate test environment, which includes a mock controller if necessary.

The code listing below demonstrates this.

Complex Helpers
To me, canonical example of a complex helper is one that includes a call to form_tag or form_for. These methods produce a div inside the form tag, and the contents of the div has been very brittle during Rails 3 development, mostly due to the snowman debate. A test shouldn't depend on the div contents, if all that matters is that there's a form in the helper's output.

This post suggests that at some point, Rails had an assert_tag_in method, which works similarly to assert_select, but takes a string input instead of testing against the current view output. Unfortunately, the method isn't available in Rails 3.

However, ActionView::TestCase provides a render method, which can be used to create fake view output. assert_select checks for the fake view output, but assert_tag doesn't, so your tests will have to stick to the former method.

The code listing below demonstrates this approach.

I wrote this post because I wanted to properly test a helper with a form tag. I spent a few hours sifting through blog posts, RDocs, LightHouse tickets and GitHub commits. I hope this post helps other developers avoid duplicating my effort.

Rails 3 makes testing helpers easy, as long as you know what methods to call. I hope you found my post useful, and I'm looking forward to your comments and suggestions!

1 comment:

  1. While this is an old post, I recently found it helpful when upgrading a legacy Rails 2.3 app. Thanks for the suggestion to render the helper and then test with assert_select.