Rspec-rails: ActionController::UrlGenerationError

Created on 30 Nov 2019  路  10Comments  路  Source: rspec/rspec-rails

While testing my controller action I am getting this routing error. I am not able to figure it out where I am doing it wrong

route
get ':user_type', to: 'user_posts#index', param: :user_type, constraints: lambda { |req| ['abc', 'def'].include?(req.params["user_type"]) }, as: :custom_posts

spec

 describe "GET #index: enabled" do
    it "returns http success" do
      get :index, params: {user_type: 'abc'}
      expect(response).to have_http_status(:success)
    end
  end

Error

ActionController::UrlGenerationError:
       No route matches {:action=>"index", :controller=>"user_posts"}

Also I tried https://github.com/rspec/rspec-rails/issues/1699

get ':user_type', to: 'user_posts#index', param: :user_type, constraints: {user_type: lambda { |req| ['abc', 'def'].include?(req.params["user_type"]) } }, as: :custom_posts

But it didn't work for me. Can anyone have a look at it

Ruby version: 2.5.3
Rails version: 5.2.2
RSpec version: 3.8.0
Rspec-rails version: 3.8.1

Most helpful comment

See aniketstiwari/practice_rails#1, you need to provide the extra param, as you've added it in your router, its not a magic keyword for the type of route your using. In future can you please try to solve these issues yourself, ask on stack overflow, or use the mailing list. We prefer that Github issues are actually used for real bug reports as our time as volunteers is limited.

All 10 comments

:wave: This is a Rails route matching issue, if you can't send the right combination of params to Rails it gives you this error.

Looking at your snippets I'm pondering if param: :user_type is the issue in your routes, as thats for overriding :id on resource which you are not using, you can check what Rails is looking for with rake routes and see what the route expects. Are you using a controller spec for this? You might consider using a request spec instead (as controller specs are no longer recommended by the rails team) and pointing directly at get "/abc".

Closing because theres nothing we can to do to fix this.

@JonRowe This is not an routing issue because I am able to run my program at rails level. Also, the reason why I am trying controller spec because I need to test request flow of this request. Besides if it was an routing issue then i would not be posting here. So, please reopen the issue or provide an answer for it

It is a routing issue because you are getting a ActionController::UrlGenerationError, which only happens from route generation issues. What is happening is you are not providing the correct parameters to Rails to generate the route, essentially you have to emulate the router. You need to be in the right context for the route to work.

@JonRowe This is not a routing issue in rails. I have created a dummy rails application
https://github.com/aniketstiwari/practice_rails

Hit this url: http://localhost:3001/abc

Started GET "/abc" for ::1 at 2019-11-30 15:42:55 +0530
Processing by UserPostsController#index as HTML
Parameters: {"param"=>:user_type, "user_type"=>"abc"}

From: /home/anikettiwari/assignment_test/app/controllers/user_posts_controller.rb @ line 3 UserPostsController#index:

    2: def index
 => 3:   binding.pry
    4: end

In rails side everything is working fine but rspec is not able to find the route

@aniketstiwari sorry I am explaining this badly, this:

get :index, params: {user_type: 'abc'}

Is a Rails call, from within RSpec, RSpec does not provide the error that occurs, you must change this line to match your route.

It works in development because the rails router is parsing your route and matching it to the correct piece of code. In tests you must give the same bits of code, there is no magic route parsing for controller specs this is one of the reasons the Rails team recommends using request / integration tests, it makes this easier to understand.

@JonRowe You mean to say that we can't write controller spec for this one.

No I'm saying if you choose to write controller specs you must provide all the parts of the route that Rails expects, to work this out you must look at your router and rake routes output and work out all the params and formats required to trigger the route.

Probably you need to add {:param=>:user_type} into your params passed in. e.g.
{:param=>:user_type, :user_type => 'abc'}

See aniketstiwari/practice_rails#1, you need to provide the extra param, as you've added it in your router, its not a magic keyword for the type of route your using. In future can you please try to solve these issues yourself, ask on stack overflow, or use the mailing list. We prefer that Github issues are actually used for real bug reports as our time as volunteers is limited.

@JonRowe
Actually now I notice why it is failing

If i provide like this it is failing
get :index, params: { param: 'user_type', user_type: 'abc' }

But as mentioned in your comment I interchange the arguments
get :index, params: {user_type: 'abc', param: :user_type}
And it works like a charm. Thanks for your help.

Initially, I have asked this question https://stackoverflow.com/questions/59099760/actioncontrollerurlgenerationerror-in-rspec but I didn't get any response there.

Just last thing why it works when I interchange the parameters

Because it has to be exactly what rails wants, and a string is not a symbol.

Was this page helpful?
0 / 5 - 0 ratings