J'ai la situation suivante:
MODIFIÉ
Dans mes routes.rb
namespace :api, defaults: { format: :json } do
namespace :v1 do
# the definitions of other routes of my api
# ...
match '*path', to: 'unmatch_route#not_found', via: :all
end
end
MODIFIÉ
Mon contrôleur:
class Api::V1::UnmatchRouteController < Api::V1::ApiController
def not_found
respond_to do |format|
format.json { render json: { error: 'not_found' }, status: 404 }
end
end
end
Mon test est comme indiqué:
require 'rails_helper'
RSpec.describe Api::V1::UnmatchRouteController, type: :controller do
describe 'get response from unmatched route' do
before do
get :not_found, format: :json
end
it 'responds with 404 status' do
expect(response.status).to eq(404)
end
it 'check the json response' do
expect(response.body).to eq('{"error": "not_found"}')
end
end
end
Cela me semble juste, mais j'ai eu la même erreur pour les deux instructions it
:
1) Api::V1::UnmatchRouteController get response from unmatched route responds with 404 status
Failure/Error: get :not_found, format: :json
ActionController::UrlGenerationError:
No route matches {:action=>"not_found", :controller=>"api/v1/unmatch_route", :format=>:json}
# /home/hohenheim/.rvm/gems/ruby-2.3.1@dpms-kaefer/gems/gon-6.1.0/lib/gon/spec_helpers.rb:15:in `process'
# ./spec/controllers/api/v1/unmatch_route_controller_spec.rb:14:in `block (3 levels) in <top (required)>'
MODIFIÉ
Le but de cette route est déclenché lorsqu'il n'y a pas d'autre route possible dans mon api, avec une réponse json 404 personnalisée . Cette route et ce contrôleur fonctionnent comme prévu en ce moment, lorsque nous accédons à des routes telles que: /api/v1/foo
ou /api/v1/bar
Comment puis-je écrire correctement les tests?
Informations supplémentaires: Rails 4.2.6, Rspec 3.5.4
2 réponses
Si vous essayez d'écrire des spécifications de routes, cela ne fonctionnera pas non plus et cela renverra quelque chose d'étrange.
Failure/Error:
expect(get("/unmatch")).
to route_to("unmatch_route#not_found")
The recognized options <{"controller"=>"unmatch_route", "action"=>"not_found", "path"=>"unmatch"}> did not match <{"controller"=>"unmatch_route", "action"=>"not_found"}>, difference:.
--- expected
+++ actual
@@ -1 +1 @@
-{"controller"=>"unmatch_route", "action"=>"not_found"}
+{"controller"=>"unmatch_route", "action"=>"not_found", "path"=>"unmatch"}
À côté de l'action not_found, il a renvoyé path => unmatch, ce qui explique peut-être pourquoi les spécifications du contrôleur ne fonctionnaient pas comme prévu. Ainsi, au lieu du test du contrôleur, vous pouvez utiliser le test de demande comme ci-dessous.
require 'rails_helper'
RSpec.describe "get response from unmatched route", :type => :request do
before do
get '/not_found', format: :json
end
it 'responds with 404 status' do
expect(response.status).to eq(404)
end
it 'check the json response' do
expect(response.body).to eq('{"error": "not_found"}')
end
end
Jetez un œil à ce lien:
https://apidock.com/rails/ActionDispatch/Routing/Mapper/Base/match
Ça dit:
Notez que: controller,: action et: id sont interprétés comme des paramètres de requête d'url et donc disponibles via des paramètres dans une action.
match ": contrôleur /: action /: id"
Votre itinéraire est:
match '*path', to: 'unmatch_route#not_found', via: :all
Votre test essaie donc de trouver une route avec: action => "not_found" à l'intérieur: controller => "api / v1 / unmatch_route". Mais votre routes.rb n'a pas cette route.
Essayez quelque chose comme ceci:
match 'unmatch_route/not_found', to: 'unmatch_route#not_found', via: :all
Si vous avez vraiment besoin d'utiliser * path, essayez ceci:
match '/:path/', :to => 'unmatch_route#not_found', :path=> /.*/, :as =>'not_found'
De nouvelles questions
ruby-on-rails
Ruby on Rails est un framework d'application web open source à pile complète écrit en Ruby. Il suit le modèle de framework MVC populaire et est connu pour son approche "convention sur configuration" pour le développement d'applications.