I get the below error ActionController::UrlGenerationError.
ActionController::UrlGenerationError:
No route matches {:action=>"/accounts/100", :controller=>"accounts"}
Below is my code which throws this error.
it "can find an account" do
Account.should_receive(:find, with: {id: 2055, authorization: #auth}
get "/accounts/100", nil, {"AUTH_TOKEN" => #auth}
hashed_response = {
"#type" => "test",
"createdAt" => "2014-07-24T15:26:49",
"description" => "Something about test",
"disabled" => false
}
expect(response.status).to eq 200
expect(response.body).to eq(hashed_response.to_json);
end
I did a google on this and came to know that there is no routes defined for this. Below is my config/routes.rb file
Rails.application.routes.draw do
resources :accounts do
resources :holders
end
end
I presume this error is coming from a controller spec? If so, you simply use a symbol representing the action you want to call, not the URL itself.
eg. this is a show action, so you would use:
get :show, id: 100
Related
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 one solution on github by changing my route but it didn't work for me
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
Finally, I got an answer. Here is the detail discussion
describe "GET #index: enabled" do
it "returns http success" do
get :index, params: { user_type: 'abc', param: :user_type }
expect(response).to have_http_status(:success)
end
end
Here is my route from routes.rb:
resources :books, :except => [:new, :edit] do
post "pull" => "books#update", :data => { "pull" => true }
rake routes shows things as expected
pull_api_v1_book POST /api/v1/books/:id/pull(.:format)
api/v1/books#update {:format=>:json, :data=>{"pull"=>true}}
Running a dev server, the route works as expected:
curl -X POST http://localhost:3000/api/v1/books/3/pull?auth_token=1234567890
My spec in in books_controller_spec.rb:
describe "pull api" do
it "should not fail" do
post :pull, params: { :id => 12 }
end
end
But the output of the spec:
Failure/Error: post :pull, params: { :id => 12 }
ActionController::UrlGenerationError:
No route matches {:action=>"pull", :controller=>"api/v1/books", :id=>12}
Why can't rspec find the route?
Controller tests in rails don't actually invoke the routing, it's only syntactic sugar for calling the controller action. Your spec should call:
post :update, params: { :id => 12 }
If you actually want to test the route you should use a request spec.
I have been at this for a few hours, still can't figure it out. I have 2 tests on 2 actions on a nested resources controller. requests is the parent resources route, and response is the nested resources route.
These 2 tests give me a no route matches error. Does not make sense. In the first test, it tries to run the update action instead of the edit. Here are my tests:
test "should get edit" do
assert_routing edit_request_response_path(#myresponse.request_id, #myresponse), { :controller => "responses", :action => "edit", :request_id => #myresponse.request_id.to_s, :id => #myresponse.id.to_s }
get :edit, params: { id: #myresponse, request_id: #myresponse.request_id }
assert_response :success
end
test "should update response" do
post :update, :request_id => #myresponse.request_id, response: { body: #myresponse.body, request_id: #myresponse.request_id, status: #myresponse.status, subject: #myresponse.subject, user_id: #myresponse.user_id }
assert_redirected_to response_path(assigns(:response))
end
Here are the errors:
3) Error:
ResponsesControllerTest#test_should_get_edit:
ActionController::UrlGenerationError: No route matches {:action=>"edit", :controller=>"responses", :params=>{:id=>"980190962", :request_id=>"999788447"}}
test/controllers/responses_controller_test.rb:43:in `block in <class:ResponsesControllerTest>'
4) Error:
ResponsesControllerTest#test_should_update_response:
ActionController::UrlGenerationError: No route matches {:action=>"update", :controller=>"responses", :request_id=>"999788447", :response=>{:body=>"This is the body", :request_id=>"999788447", :status=>"draft", :subject=>"This is the subject", :user_id=>"175178709"}}
test/controllers/responses_controller_test.rb:48:in `block in <class:ResponsesControllerTest>'
In this case you might want to use shallow nesting since there is no reason to go through request if you can get to a response by /response/:id.
resources :requests, shallow: true do
resources :response
end
http://guides.rubyonrails.org/routing.html#nested-resources
test "should get edit" do
assert_routing edit_response_path(#myresponse), { :controller => "responses", :action => "edit", :id => #myresponse.id.to_s }
get :edit, params: { id: #myresponse, request_id: #myresponse.request_id }
assert_response :success
end
However naming your business logic objects Request and Response is a big misstake. These are already key concepts in Rails which correspond to the request from the client and the response sent to the client by rails.
You will end up confusing yourself and any poor sucker that has to work on the project. Plus you will end up masking the request and response methods that are pretty important parts of the ActionController API.
Use some other synonym instead.
so far in routes.rb
match 'campaigns_mobile_application', to: 'campaigns#update_mobile_store_application', via: [:post, :get]
in spec_helper.rb
config.include Rails.application.routes.url_helpers
in controller_spec.rb
get campaigns_mobile_application_path format: :json # and here I have error
ok, I have error:
ActionController::RoutingError No route matches {:controller=>"campaigns", :action=>"/api/campaigns_mobile_application.json"}
change routes.rb now:
resources :campaigns do
match 'mobile_application', to: 'campaigns#update_mobile_store_application', via: [:post, :get]
end
and also spec:
get campaign_mobile_application_path campaign_id: #campaign.id, format: :json
and again I catch error:
ActionController::RoutingError:
No route matches {:controller=>"campaigns", :action=>"/api/campaigns/6775/mobile_application.json"}
How to fix this?
UPD:
I try different magic with on: :member, on: :collection, as: :name and other stuff.
Seems that I completely doesn't understand routing.
routes.rb
resources :campaigns do
match :mobile_applications, to: 'campaigns#update_mobile_store_applications',
via: [:post, :get], on: :member, as: :mobile_applications
end
**rake routes **
mobile_applications_campaign POST|GET /api/campaigns/:id/mobile_applications(.:format) campaigns#update_mobile_store_applications
controller.rb
def update_mobile_store_applications
render: json: { }, status: :ok
end
spec.rb
get mobile_applications_campaign_path campaign_id: #campaign.id, format: :json
generate error:
Failure/Error: get mobile_applications_campaign_path campaign_id: #campaign.id, format: :json
ActionController::RoutingError:
No route matches {:action=>"update_mobile_store_applications", :controller=>"campaigns", :campaign_id=>8059, :format=>:json}
change request to this one (rename parameter):
get mobile_applications_campaign_path id: #campaign.id, format: :json
still generate error: ( different error )
Failure/Error: get mobile_applications_campaign_path id: #campaign.id, format: :json
ActionController::RoutingError:
No route matches {:controller=>"campaigns", :action=>"/api/campaigns/8108/mobile_applications.json"}
UPD2
This code works well on app but not in testing.
UPD3
This code works well on testing too now! Yeah!
get :update_mobile_store_applications, id: #campaign.id, format: :json
get :mobile_applications_campaign_path, id: #campaign.id, format: :json
The format was incorrect look here: https://github.com/everydayrails/rails-4-1-rspec-3-0/blob/master/spec/controllers/contacts_controller_spec.rb
This code is part of a Everyday Rails Testing book, a very good book for learn testing with rspec on Rails
my
describe PaymentController do
it 'should assign amount_to_pay' do
get bank_payment_path, {id: "1"}
expect(assigns[:amount_to_pay]).to eq "123"
end
end
my error:
Error: ActionController::RoutingError: No route matches {:action=>"bank", :controller=>"payment"}
and rake routes:
bank_payment GET /payment/:id/bank(.:format) payment#bank
What is wrong there?
The request should be:
get :bank, id: "1"