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 03: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 08: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 10: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.

Trackback URL: http://www.viget.com/trackback/1160/

A Development Community for Viget Labs and Beyond

Every team member here at Viget Labs strives to be an innovator. We members of the development team are no different - that's why we're constantly engaging in community discussions and exploring the unknown that is the next generation of open-source web applications.

Viget Is Hiring!

Viget has job openings for Ruby Developers, Interns, and Front-End Developers. Learn More »

Recent Comments

I have used several different strategies for achieving this, and have settled on the plugin seed_fu to accomplish this task. Because it uses plain ruby files you have quite a few more options for manipulating your seed data as opposed to using fixtures. I have found that this lets me create seed data that is much less brittle than fixtures can be. You can find seed_fu on...