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
intmarinoreturn0 15 août 2017 à 06:48

2 réponses

Meilleure réponse

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
1
Tai 15 août 2017 à 18:04

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'
1
Community 20 juin 2020 à 09:12