Close and Go BackBack to Viget

Testing Helpers In Rails 2.1

Justin Marney
Justin Marney, Web Developer, June 17, 2008 3

The conventional approach to testing helpers in Rails has, until recently, always been relatively subjective. I have come across different strategies including generators, plugins and hand-hacked setups depending on where I looked. In sharp contrast, the controller testing convention has been DRY'd up and moved into the framework in the form of the ActionController::TestCase class. Fortunately, Brian has been working on some helper testing tools and recently stumbled across the ActionView::TestCase class. If you have been looking for a convenient, framework supported way to test your helpers, look no further. This class provides the same conventions as ActionController::TestCase and makes testing helpers a breeze.

Test Your Helpers Using ActionView::TestCase
Here is an example that shows how to use ActionView::TestCase along with Brian's assert_tag_in. First, create a test named HelperNameTest and inherit from ActionView::TestCase. Then just call your helper methods from your tests, it's that easy.

module ApplicationHelper
  def special_header()
    content_tag :div do
      link_to('Edit Profile', edit_account_path)
    end
  end
end

class ApplicationHelperTest < ActionView::TestCase
  def test_special_header_should_render_edit_link
    tag = special_header(:edit_profile => true)
    assert_tag_in(tag, :a, :attributes => {:href => edit_account_path})
  end
end

Worth noting here is the ability to test methods that rely on url_for without needing to create a temporary controller in your own testing code. I also want to point out that Chu Yeow did cover using ActionView::TestCase in his Living on the Edge series, but it totally slipped past me :)

Update

ActionView::TestCase is not loaded automatically. Be sure to require 'action_view/test_case' in your test_helper.

Andy said on 06/20 at 04:20 PM

Thanks for the post.

I tried the code above in Rails 2.1.0, but I’m getting the following error: ./test/unit/application_helper_test.rb:1: uninitialized constant ActionView (NameError)

Here’s the code I’m using:
/app/helpers/application.rb
module ApplicationHelper
def title(page_title)
content_for(:title) { page_title }
end
end

/test/unit/application_helper_test.rb
class ApplicationHelperTest < ActionView::TestCase
assert true
end

Any ideas on why this isn’t working for me?

Justin Marney said on 06/26 at 09:36 AM

@Andy, You’ll need to require ‘action_view/test_case’ somewhere in your test setup.  I have mine in my test_helper.rb which gets required in every test.  Thanks for catching this, I’ll update the post to be more clear.

James Adam said on 07/25 at 11:35 AM

It’s worth noting that the only reason link_to works in this example is because it’s calling a named route.

ActionView::TestCase will only instantiate a controller for you if you are trying to call one of the methods generated for you by routing. If you try and use anything that eventually hits url_for, you’re out of luck (or at least need to work a bit harder). As an example, link_to("foo", bar_path) would work, but link_to("foo", :controller => “bar") will not.

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


How many minutes in an hour?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.