2017-08-15 1 views
1

Je la situation suivante:Comment tester un itinéraire not_found sur mesure dans des rails

ÉDITÉ

Dans mon 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 

ÉDITÉ

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 le montre:

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 

Il me semble juste, mais je suis la même erreur pour les deux it statments:

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/[email protected]/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)>' 

ÉDITÉ

Le but avec cette route est déclenché quand il n'y a pas d'autre itinéraire possible dans mon API, avec une coutume j réponse 404 fils. Cette route et le contrôleur fonctionne comme prévu en ce moment, lorsque nous accédons à des routes comme: /api/v1/foo ou /api/v1/bar

Comment puis-je écrire les tests correctement?

Informations complémentaires: Rails 4.2.6, 3.5.4 Rspec

+0

avez-vous essayé d'ajouter comme: "not_found" dans votre itinéraire? –

+0

si vous voulez écrire 'match '* chemin', à: 'unmatch_route # not_found', comme: 'not_found', via:: all' Je l'ai fait maintenant, mais ne fonctionne toujours pas – intmarinoreturn0

Répondre

1

Si vous essayez d'écrire les spécifications des routes, il ne fonctionnera pas trop et retournera 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"} 

A côté une action not_found, il est revenu path => unmatch que peut-être pourquoi les spécifications du contrôleur ne fonctionne pas comme prévu. Ainsi, au lieu du test du contrôleur, vous pouvez utiliser le test de requête 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 
+0

J'ai fait la spécification de l'itinéraire comme dans ce [gist] (https://gist.github.com/Marinofull/c8d750b826ad2f969ea625e8efbb2545) Mais il suffit de tester s'il y a un itinéraire correspondant, maintenant j'essaie de tester le contenu de la réponse de cette route. – intmarinoreturn0

+0

Ça a marché, merci! Ce n'est pas encore un contrôleur de spec comme je voudrais, mais je signalerai cette réponse comme le meilleur pour l'instant – intmarinoreturn0

0

Jetez un oeil à ce lien:

https://apidock.com/rails/ActionDispatch/Routing/Mapper/Base/match

Il dit:

Notez que: contrôleur, : action et: id sont interprétés comme des paramètres de requête url et sont donc disponibles via les paramètres d'une action.

Match ": controller /: action /: id"

Votre itinéraire est le suivant:

match '*path', to: 'unmatch_route#not_found', via: :all 

donc votre test tente de trouver un itinéraire avec: action => "not_found" à l'intérieur : controller => "api/v1/unmatch_route". Mais votre routes.rb n'a pas cette route.

essayer quelque chose comme ceci:

match 'unmatch_route/not_found', to: 'unmatch_route#not_found', via: :all 

Si vous avez vraiment besoin d'utiliser * chemin essayez ceci:

match '/:path/', :to => 'unmatch_route#not_found', :path=> /.*/, :as =>'not_found' 
+0

J'ai essayé, en changeant' match 'par' get' et aussi en ajoutant ', via:: all' à la fin de votre suggestion et il s'est arrêté pour me rediriger vers mon json personnalisé. Il renvoie l'erreur ** Routing Error ** par défaut des rails. Et oui, j'ai vraiment besoin d'utiliser * path, afin de correspondre à chaque route qui ne correspond pas aux routes écrites avant cette ligne – intmarinoreturn0

+0

Avez-vous essayé d'exécuter des routes rake, et vérifié quel est le format de votre route? –

+0

J'ai ce 'api_v1_not_found /api/v1/*path(.format) api/v1/unmatch_route # not_found {: format =>: json}' pour la route 'match '* chemin', à: 'unmatch_route #not_found ', as:' not_found ', via:: all' et: '/api/v1/*path(.format) api/v1/unmatch_route # not_found {: format =>: json}' pour: 'match '* chemin', à: 'unmatch_route # not_found', via:: all' Je ne suis pas sûr comment puis-je utiliser cette information – intmarinoreturn0