Our team wrote helper that would render a remote_function call as part of its contents:
require 'test_helper'
require 'action_view/test_case'
class ApplicationHelperTest <  < method =""> :get, :controller => 'main', :action=> 'open_item', :id => 1)
 end
end
Executing this test resulted in an odd error:
[root@new-host-2 qme]# ruby test/unit/application_helper_test.rb --name test_demonstrates_bug
Loaded suite test/unit/application_helper_test
Started
E
Finished in 0.516956 seconds.
1) Error:
test_demonstrates_bug(ApplicationHelperTest):
NoMethodError: undefined method `protect_against_forgery?' for #applicationhelpertest:0x2a97ff0d68
  /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_controller/test_process.rb:467:in `method_missing'
  /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_view/test_case.rb:55:in `method_missing'
  /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_view/helpers/prototype_helper.rb:1053:in `options_for_ajax'
  /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_view/helpers/prototype_helper.rb:443:in `remote_function'
  test/unit/application_helper_test.rb:17:in `test_demonstrates_bug'
  /usr/lib64/ruby/gems/1.8/gems/activesupport-2.1.2/lib/active_support/testing/setup_and_teardown.rb:67:in `__send__'
  /usr/lib64/ruby/gems/1.8/gems/activesupport-2.1.2/lib/active_support/testing/setup_and_teardown.rb:67:in `run'
1 tests, 0 assertions, 0 failures, 1 errors
I do not know what the root of this was, but I figured that my test did not care about protecting against forgery so I defined the method:
 def protect_against_forgery?
 end
Then I ran the test again, which resulted in a new error:
1) Error:
test_demonstrates_bug(ApplicationHelperTest):
NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.url_for
   /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_view/helpers/url_helper.rb:71:in `send'
   /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_view/helpers/url_helper.rb:71:in `url_for'
   /usr/lib64/ruby/gems/1.8/gems/actionpack-2.1.2/lib/action_view/helpers/prototype_helper.rb:461:in `remote_function'
   test/unit/application_helper_test.rb:20:in `test_demonstrates_bug'
   /usr/lib64/ruby/gems/1.8/gems/activesupport-2.1.2/lib/active_support/testing/setup_and_teardown.rb:67:in `__send__'
   /usr/lib64/ruby/gems/1.8/gems/activesupport-2.1.2/lib/active_support/testing/setup_and_teardown.rb:67:in `run'
1 tests, 0 assertions, 0 failures, 1 errors
Reading the source code it turns out that UrlHelper is trying to invoke @controller.url_for... really? I thought that it was initialized in the TestCase setup method? Turns out that it only creates a controller in the event a method is missing on in the TestCase...
 
     def method_missing(selector, *args)
       controller = TestController.new
       return controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
       super
     end
I then initialized the controller as an instance member in setup() and things worked just fine.
 
    setup :setup_with_helper_class
    def setup_with_helper_class
      if helper_class && !self.class.ancestors.include?(helper_class)
        self.class.send(:include, helper_class)
      end
      @controller = TestController.new
    end
I am not sure if all of these crazy things I did were good or bad things, particularly if I have forever inhibited my ability to protect_from_forgery in my tests but I guess I can live with it until I can file a request for fix with the Rails team.
Hope this helps...
1 comment:
Post a Comment