ActionController::RoutingError in controller specs #39

Closed
senny opened this Issue Jun 15, 2012 · 17 comments

Comments

Projects
None yet
Owner

senny commented Jun 15, 2012

I'm using rspec and since i've installed journey 1.0.4 my controller-specs are failing. I now receive: ActionController::RoutingError with No route matches {:term=>"gitt", :controller=>"some_controller", :action=>"autocomplete"}
. The code lives inside a rails engine and it is possible that I don't have any routes setup because they are defined in the hosting rails app. Do I need to fiddle with the dummy application?

Everything worked with journey 1.0.3. I'm not sure if this is a regression or if it was just a coincidence that it worked before.

we're also experiencing this exact issue.

Owner

tenderlove commented Jun 15, 2012

1.0.4 fixed a regression from Rails 3.1 where the router would return a route even if the constraints a user passed in didn't match anything. Can you take a look at this ticket and see if it might relate?

If it doesn't seem to relate to your issue, can you get me some repro steps? (Even a full rails app on GH will be fine).

Thanks!

hardipe commented Jun 16, 2012

I had the same problem, but found out that my specs were not passing in required parameters - exactly what was fixed in 1.0.4, so the exceptions you are getting are most likely justified. @senny, try checking if the route in routes.rb, that is supposed to be matched, requires any other extra parameters in addition to :term

I have the same problem: in my functional tests I sometimes use dummy controllers in order to test base controllers (like ApplicationController) or modules that supposed to be included in a controller. Of course there is no route for these dummy controllers. With journey 1.0.3 this was not a problem (I am not testing the route, I am just testing actions, I don't care if one or many URLs point towards this action), but with journey 1.0.4 it is not possible anymore.

The following test demonstrate that: https://gist.github.com/2961808

If the behavior of journey 1.0.4 is on purpose, maybe rails or testing framework should ignore or avoid this exception (why route resolution is called after all?).

Meanwhile, the solution I found is to add this in routes.rb

match ':controller/:action' if  Rails.env.test?

Yes, pretty much same thing as with eric-smartlove issue. I am testing routes specifically passing all the required parameters, but in actions specs I stub most of the parameters, thus just calling actions. With 1.0.3 that was not a problem, but specs breaks with 1.0.4. Not sure if I want to use solution above, because somewhere within I feel, like it may create false-positive tests sometimes.

miyagawa commented Jul 2, 2012

Same problem here with mounted engine (doorkeeper gem specifically).

The problem happens with both rspec and simple ActionController::TestCase. Reproducible sample project is posted on https://github.com/miyagawa/rails-journey-mount-engine

@ppokrovsky @eric-smartlove

The easiest solution I've found so far is to use with_routing in the tests:

def perform_request
  with_routing do |map|
    map.draw { get "dummy" => "dummy#index" }
    get :index
  end
end

@semaperepelitsa

Thank you, it works perfectly.

If it can help, I've added the following code in my test_helper.rb:

class ActionController::TestCase
  # Avoid journey routing checking.
  #
  # journey does not allow to call an action which has no route that points to it since version 1.0.4.
  # This method temporally defines a catch-all route to allow a call on any action.
  # This is useful for fake controllers, defined in test.
  # @see https://github.com/rails/journey/issues/39#issuecomment-7007173
  def skip_routing
    with_routing do |map|
      map.draw do
        match ':controller/:action'
      end
      yield
    end
  end
end

So when I want to use a dummy controller, I just write:

class TestableController < ActionController::Base
  def public_success_action
    render text: 'rendered content here'
  end
end

class MyTest < ActionController::TestCase
  tests TestableController

  test "my test" do
    skip_routing do
      get :public_success_action
      assert_response :success
    end
  end
end

Maybe this ticket can be closed?

Owner

pixeltrix commented Aug 9, 2012

@miyagawa the reason your test is failing is because you're trying to test a isolated engine route which is a completely different routeset than the main application so when trying to generate the request url from the controller, action and params it can't find a matching route. If you setup the routes correctly then the test works, e.g:

module Doorkeeper
  class TokensControllerTest < ActionController::TestCase
    setup do
      @routes = Engine.routes
    end

    test "should fail" do
      post :create
      assert_response :unauthorized
    end
  end
end

To everyone else - I wouldn't recommend adding a match all route in testing as you may end up masking an error which will bite you in production. You should provide the correct parameters to the process call so that it can recreate the request url.

I'm going to close this ticket as it appears to be the same as #40 and #42 - failure to fully specify the params to a functional test. If anyone can provide code which demonstrates something other than this I'll reopen this and take another look.

pixeltrix closed this Aug 9, 2012

Here's an alternate solution to the problem of testing base controllers in your ApplicationController spec:
If you define the fake controller that you are testing before making the request, it appears that the routes work properly.

controller do
  def index
    render text: "yay!"
  end
end

it 'does things' do
  get :index
end

@pixeltrix I guess the best would to write this inside test_helper.rb (I've tested it and it works):

module MyEngine
  class ActionController::TestCase
    setup do
      @routes = Engine.routes
    end
  end
end

This Rails issue is somehow related to this one.
They should fix the Rails engine template generation (including @routes = Engine.routes thing) so it works out of the box.

raecoo commented Jan 9, 2013

I have same problem and downgrade to 1.0.3 then works well.

rspec (2.12.0)
rspec-rails (2.12.0)
rails (3.2.11)

I have the same issue: my controller specs fails when I'm using journey 1.0.4 and it works fine with 1.0.3. I'm using Rails 3.2.11 + Rspec 2.12.0.

Anybody have a solution?

Just inherited a project that was running on Rails 3.2 with Journey 1.0.3. Upgraded to Rails 3.2.11 / Journey 1.0.4 and controller specs went to shit.

Owner

jeremy commented Jan 16, 2013

Looks like backporting rails/rails@f1d8f2a to journey should fix this.

Owner

pixeltrix commented Jan 16, 2013

@robbyrussell can you post a small example of the relevant routes and specs, thanks. As @jeremy points out backporting f18d8f2a may help if you're routes have defaults that aren't part of the path - do yours match this pattern? Another cause may be missing parent ids when testing a nested controller - previously these would've passed.

Whilst I'm loathe to backport due to it being a change of behavior enough reports of this problem keep occurring that it may be better in the long run.

erichmenge referenced this issue in EDMC/api-versions May 27, 2013

Closed

No Route Matches? #6

As you guys can see from that linked issue, I think there appears to be a definite bug going on here. I'm unable to test routes that are defined in my application itself due to the constraints set on those routes, even if I meet the constraints from the test. curl, with the same constraints, will match the route and complete the action.

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