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