Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Tests fail to recognize custom actions

#489

Suppose we define a custom action baz in the Foobars controller:

map.resources :foobars, :collection => { :baz => :get }

Then we define it in the controller:

def baz
  raise
end

Finally, in the functional test we have:

def test_baz
  get :baz
end

The result of running the test is

test_baz(FoobarsControllerTest):

ActionController::UnknownAction: No action responded to baz

instead of the expected runtime error.

Even stranger, if we create a template file, the test passes:

touch app/views/foobars/baz.html.erb

Now the test recognizes get :baz, but we can tell that it's still not hitting the action since the test passes; the raise inside the baz action never gets called.

Reported by Michael Hartl · June 25th, 2008 @ 11:12 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Michael Hartl
    Michael Hartl
    • Tag set to bug, routing, tests

    N.B. I've reproduced the problem with the freshest copy from GitHub, so apparently it hasn't been fixed yet.

    June 25th, 2008 @ 11:27 PM

  2. Tarmo Tänav
    Tarmo Tänav

    Does the 'baz' action work in development mode?

    As far as I'm aware in functional tests "get" does not look at routes at all so it should work no matter what you have in routes.

    June 28th, 2008 @ 02:53 PM

  3. Michael Hartl
    Michael Hartl

    The 'baz' action works everywhere but in Rails 2.1 tests. I discovered this problem when upgrading Insoshi to Rails 2.1; suddenly several passing specs failed. Initially I suspected RSpec, but eventually I traced the problem to Rails itself.

    I'm not positive it's a routing issue—given what you say, that now seems unlikely—but it's definitely a Rails 2.1 testing issue.

    June 28th, 2008 @ 05:05 PM

  4. Tarmo Tänav
    Tarmo Tänav

    Would you mind trying git bisect to identify the exact rails changeset that caused the problem?

    Nothing more than cd vendor/rails (assuming you have git clone'd rails there):

    git bisect start v2.0.0 v2.1.0

    and then run your tests and according to if they fail or not run git bisect good / git bisect bad and git will tell you which revision caused the problem.

    June 28th, 2008 @ 05:15 PM

  5. Michael Hartl
  6. Michael Hartl
    Michael Hartl

    This is so weird. In a completely fresh install it now works. There must be something else in my config that's interacting with Rails 2.1 in some subtle way. Go ahead and mark this ticket "invalid".

    Unfortunately, my problem isn't solved, since I still have an upgraded Insoshi where everything works but this weird routing issue. I'd be surprised if I'm the only one with this problem. I'll let you know if the eventual solution is generally useful.

    N.B. As soon as I wrote "definitely a Rails 2.1 testing issue", I tried to edit it to say "_seems_ to be...", but Lighthouse wouldn't let me. This is why. :-(

    June 28th, 2008 @ 06:05 PM

  7. Michael Hartl
    Michael Hartl

    OK, this is weird, and (alas) probably sloppiness on my part. The problem seems to be that my custom action inside Insoshi is called 'verify', which apparently conflicts with some change made during the 2.1 upgrade. What's strange is that this name conflict possibility occurred to me almost immediately, and I thought for sure that I had tested the possibility and found that other routes (such as 'baz') also failed. I can't reproduce it now, and renaming my 'verify' action to 'verify_email' appears to solve the problem.

    Oddly, doing a git bisect shows the problem persisting all the way down to 2.0, even for a fresh project with nothing but a 'verify' action. And yet, for a fresh application generated with Rails 2.0.2, the custom 'verify' action works fine. (I should mention that 'verify' in fact works fine in every case; it's just the tests that break.) So it is a Rails 2.1 testing issue, but it appears not to be generic, affecting only tests of custom actions called 'verify' in projects generated using the 2.1 version of the 'rails' script.

    At this point, since my problem is solved, I'm ready to move on to bigger and better things. Sorry for the trouble, and thanks for your help!

    June 28th, 2008 @ 06:53 PM

  8. Tarmo Tänav
    Tarmo Tänav

    verify is used by mocha, from actionpack/test/controller/base_test.rb :

        # Mocha adds some public instance methods to Object that would be
        # considered actions, so explicitly hide_action them.
        def hide_mocha_methods_from_controller(controller)
          mocha_methods = [
            :expects, :mocha, :mocha_inspect, :reset_mocha, :stubba_object,
            :stubba_method, :stubs, :verify, :__metaclass__, :__is_a__, :to_matcher,
          ]
          controller.class.send!(:hide_action, *mocha_methods)
        end
    

    June 28th, 2008 @ 07:01 PM

  9. Tarmo Tänav
    Tarmo Tänav

    Perhaps it would be a good idea to make get/post test helper methods to rais an exception if one of the mocha method names is called as an action. Though it would be of limited usefulness because the action would still be untestable.

    June 28th, 2008 @ 07:02 PM

  10. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to invalid

    June 28th, 2008 @ 08:51 PM