This project is archived and is in readonly mode.

#489 ✓invalid
Michael Hartl

Tests fail to recognize custom actions

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

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.

Comments and changes to this ticket

  • Michael Hartl

    Michael Hartl June 25th, 2008 @ 11:27 PM

    • 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.

  • Tarmo Tänav

    Tarmo Tänav June 28th, 2008 @ 02:53 PM

    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.

  • Michael Hartl

    Michael Hartl June 28th, 2008 @ 05:05 PM

    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.

  • Tarmo Tänav

    Tarmo Tänav June 28th, 2008 @ 05:15 PM

    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.

  • Michael Hartl
  • Michael Hartl

    Michael Hartl June 28th, 2008 @ 06:05 PM

    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. :-(

  • Michael Hartl

    Michael Hartl June 28th, 2008 @ 06:53 PM

    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!

  • Tarmo Tänav

    Tarmo Tänav June 28th, 2008 @ 07:01 PM

    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
    
  • Tarmo Tänav

    Tarmo Tänav June 28th, 2008 @ 07:02 PM

    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.

  • Jeremy Kemper

    Jeremy Kemper June 28th, 2008 @ 08:51 PM

    • State changed from “new” to “invalid”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages