Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #3775 (closed defect: invalid)

Opened 2 years ago

Last modified 2 years ago

can't write functional test for helpers which use ActionView methods

Reported by: rick@rickbradley.com Assigned to: David
Priority: normal Milestone:
Component: ActionPack Version: 1.0.0
Severity: normal Keywords: helper functional test link_to actionview
Cc:

Description

(I made a similar post to the RoR mailing list and asked around on IRC but noone seems to have a handy answer (I also noticed that Typo doesn't do this sort of testing of their helpers either, so no help from my favorite source of silent advice).)

We've been having problems writing functional tests for helper methods that rely on ActionView methods. Here's a specific example.

In application_helper.rb I've got a method called 'party_link()':

  def party_link(party)
    link_to party.full_name, { :controller => 'contacts',
                               :action => 'view',
                               :category => party.category_name,
                               :id => party.id },
            :class => 'a2'
  end

It takes a Party object (person, organization...) and returns an HTML link to that party's contact page. Simple enough. And it appears to work well enough from the browser.

We want to test it, though, so we want to write a functional test that fires fixture Party data at it and ensure that it returns reasonable links, for some value of reasonable.

Since it's not in a particular controller's helper file (since it will be used by many controllers), we will create a trivial controller for use in testing. The problem we run into is that we can't seem to get the ActionView methods required to run party_link() visible while testing. Here's the functional test:

require File.dirname(__FILE__) + '/../test_helper'
require File.dirname(__FILE__) + '/../../app/controllers/application'
require File.dirname(__FILE__) + '/../../app/helpers/application_helper'
require 'action_view'

module LoginSystem
  def unprotected?() true; end # drop login protection for this test controller
end

# dummy controller to drive helper tests
class HelperController < ActionController::Base
  include ApplicationHelper
  include ActionView
end

class HelperControllerTest < Test::Unit::TestCase
  fixtures :party

  include ApplicationHelper
 
  def setup
    @controller = HelperController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
  end

  # Test party_link function passing staff
  def test_party_link_staff
    link_data = @controller.party_link(party(:twburges))
  end    
end

Note that we're not even getting to an assert_* in test_party_link_staff(), because, well, we tried, and we just get an error, so we culled the assertions from the code I'm sending (so as not to confuse the issue).

1) Error:

test_party_link_staff(HelperControllerTest): NoMethodError: undefined method `link_to' for #<HelperController:0xb69e32d0>

./test/functional/../../app/helpers/application_helper.rb:170:in `party_link' ./test/functional/bad_test.rb:30:in `test_party_link_staff'

Currently we're stubbing link_to() and checking that it gets called, which is The Wrong Way to fix the problem. We can 'include' ActionView, ActionView::Helpers, ActionView::Helpers::UrlHelper and get past link_to (and, I think url_for) but end up blowing on tag_options (IIRC). Seems like there must be a simpler and more straightforward way to do this, that I'm sure I missed in Rails 101.

What I'm looking for is a simple (perhaps undocumented?) way to include/require/extend something simple and allow my helpers to get access to the functionality they would normally have when running during the normal request-response cycle. Stubbing methods turns black-box testing into white-box testing and really defeats the purpose of "integration" testing by not allowing for true integration. Having to include/require every dependent module also creates white-box testing, artificial integration, and makes the tests very fragile (dependent upon the internals of Rails, which they shouldn't have to know about).

Change History

02/09/06 21:06:02 changed by anonymous

  • status changed from new to closed.
  • resolution set to invalid.

invalid -- not a bug. dupe question on the rails-core ML