Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Obscure error message in the tests if using undefined class method in controller #9933

Closed
khustochka opened this Issue Mar 26, 2013 · 8 comments

Comments

Projects
None yet
7 participants
Contributor

khustochka commented Mar 26, 2013

Imagine I have a controller and call some method on it that is missing:

class ImagesController < ApplicationController
  unexistent_method # method with such name is not defined

  def index
  end

end

(actually I ran into this bug when I tried to call caches_action without proper gem)

And I have a test

class ImagesControllerTest < ActionController::TestCase

  def test_index
    get :index
  end
end

When I run the tests with rails test test/functional/images_controller_test.rb I get the following obscure error:

ERROR ImagesControllerTest#test_get_index (0.59s)
  RuntimeError:   @controller is nil: make sure you set it in your test's setup method.
  /home/vk/.rvm/gems/ruby-2.0.0-p0@rails4/bundler/gems/rails-2d33796457b1/actionpack/lib/action_controller/test_case.rb:631:in `block in check_required_ivars'
  /home/vk/.rvm/gems/ruby-2.0.0-p0@rails4/bundler/gems/rails-2d33796457b1/actionpack/lib/action_controller/test_case.rb:629:in `each'
  /home/vk/.rvm/gems/ruby-2.0.0-p0@rails4/bundler/gems/rails-2d33796457b1/actionpack/lib/action_controller/test_case.rb:629:in `check_required_ivars'
  /home/vk/.rvm/gems/ruby-2.0.0-p0@rails4/bundler/gems/rails-2d33796457b1/actionpack/lib/action_controller/test_case.rb:531:in `process'
  /home/vk/.rvm/gems/ruby-2.0.0-p0@rails4/bundler/gems/rails-2d33796457b1/actionpack/lib/action_controller/test_case.rb:64:in `process'
  /home/vk/.rvm/gems/ruby-2.0.0-p0@rails4/bundler/gems/rails-2d33796457b1/actionpack/lib/action_controller/test_case.rb:468:in `get'
  test/functional/images_controller_test.rb:11:in `block in <class:ImagesControllerTest>'

If there are many tests in the file, the first one fails with this error but the following ones fail with different kinds of errors, e.g. saysing that action is missing from the controller while the action is actually there. Or sometimes it looks that request got to the controller but the setup block was not executed.


This error was also happenning on 4.0.0.beta1, before rake test was switched to rails test.

As a comparison, on 3.2.13 such test just fails to start with comprehensive message

undefined local variable or method `unexistent_method' for ImagesController:Class (NameError)
Member

senny commented Mar 26, 2013

I'll take a look and report back.

Contributor

khustochka commented Mar 26, 2013

This is a minimalistic demo app: https://github.com/khustochka/cache_sweeper_fail

It actually demonstrates bug in rails-observers that makes cache_sweeper a missing method. And the missing method is what we need. The test output is as follows:

  1) Error:
PostsControllerTest#test_should_create_post:
RuntimeError: @controller is nil: make sure you set it in your test's setup method.
    test/controllers/posts_controller_test.rb:21:in `block (2 levels) in <class:PostsControllerTest>'
    test/controllers/posts_controller_test.rb:20:in `block in <class:PostsControllerTest>'

  2) Error:
PostsControllerTest#test_should_destroy_post:
AbstractController::ActionNotFound: The action 'destroy' could not be found for PostsController
    test/controllers/posts_controller_test.rb:44:in `block (2 levels) in <class:PostsControllerTest>'
    test/controllers/posts_controller_test.rb:43:in `block in <class:PostsControllerTest>'

  3) Error:
PostsControllerTest#test_should_get_edit:
NameError: undefined local variable or method `set_post' for #<PostsController:0x94e1bc4>
    test/controllers/posts_controller_test.rb:33:in `block in <class:PostsControllerTest>'

  4) Error:
PostsControllerTest#test_should_get_index:
ActionView::Template::Error: undefined method `each' for nil:NilClass
    app/views/posts/index.html.erb:15:in `_app_views_posts_index_html_erb__1066215553_80250650'
    test/controllers/posts_controller_test.rb:9:in `block in <class:PostsControllerTest>'

  5) Error:
PostsControllerTest#test_should_get_new:
ActionView::Template::Error: First argument in form cannot contain nil or be empty
    app/views/posts/_form.html.erb:1:in `_app_views_posts__form_html_erb___298614731_83449880'
    app/views/posts/new.html.erb:3:in `_app_views_posts_new_html_erb__673722478_83319500'
    test/controllers/posts_controller_test.rb:15:in `block in <class:PostsControllerTest>'

  6) Error:
PostsControllerTest#test_should_show_post:
NameError: undefined local variable or method `set_post' for #<PostsController:0x9f6db10>
    test/controllers/posts_controller_test.rb:28:in `block in <class:PostsControllerTest>'

  7) Error:
PostsControllerTest#test_should_update_post:
AbstractController::ActionNotFound: The action 'update' could not be found for PostsController
    test/controllers/posts_controller_test.rb:38:in `block in <class:PostsControllerTest>'

Here you can see the whole bunch of error messages: @controller is nil in the 1st test, The action could not be found for valid actions, as well as evidences of setup not beings executed: undefined method 'each' for nil:NilClass

senny added a commit to senny/rails that referenced this issue Mar 27, 2013

`#determine_constant_from_test_name` does not swallow NoMethodErrors.
Closes #9933.

Since `NoMethodError` is a subclass of `NameError` determining
the constant from a test name silently swalled them.

@fxn fxn closed this Mar 28, 2013

Contributor

khustochka commented Mar 28, 2013

Thanks.

Hey I am also facing the same issue with rails 4 any solution ???

Member

robin850 commented Feb 28, 2014

@peeyushsingla : Could you provide an executable gist to showcase the problem ? I'm not able to reproduce it with 4.0.3 or master.

https://github.com/peeyushsingla/rc89 used sweeper to do basic cache expiration not worked.

Member

robin850 commented Mar 2, 2014

@peeyushsingla : Ugh, you are right ; this problem remains with constants that do not exist. To reproduce, it's as simple as:

$ rails new new_app && cd new_app
$ rails g controller foo bar
$ echo "include FooBar" >> app/controllers/foo_controller.rb
$ rake test

Actually I think that this is not so easy to isolate inside an executable gist since it's Ruby which is raising the error, not Active Support. I guess that's because eager loading is not involved in the gist.

@robin850 robin850 reopened this Mar 2, 2014

Contributor

laurocaetano commented Apr 3, 2014

I tried to fix this issue in #14574, but it seems we can not simply raise NameError there. The build has failed in a lot of places. I'll close the PR until we find the right way to fix it.

@robin850 robin850 modified the milestones: 4.0.6, 4.0.0 Apr 3, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 10, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 12, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 12, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 13, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 18, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 20, 2014

@rafaelfranca rafaelfranca modified the milestones: 4.0.10, 4.1.7 Aug 21, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Aug 27, 2014

tgxworld added a commit to tgxworld/rails that referenced this issue Sep 1, 2014

@senny senny closed this in #16450 Sep 2, 2014

seuros added a commit to seuros/django that referenced this issue Sep 2, 2014

trungpham added a commit to trungpham/rails that referenced this issue Sep 18, 2014

sachin004 added a commit to sachin004/rails that referenced this issue Dec 13, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment