Подтвердить что ты не робот

Нужны ли маршруты маршрутизации для перенаправления маршрутов? [RSpec]

После довольно глубокого изучения этой проблемы я пришел в тупик между моим пониманием документации и результатами.

Согласно https://www.relishapp.com/rspec/rspec-rails/v/2-8/docs/routing-specs/route-to-matcher, мы сможем написать следующее:

#rspec-rails (2.8.1)
#rspec (>= 1.3.1)
#rspec-core (~> 2.8.0)

# routing spec
require "spec_helper"

describe BusinessUsersController do
  describe "routing" do
    it "routes to some external url" do
      get("/business_users/7/external_url").should route_to("http://www.google.com")
    end
  end
end

# routes.rb
BizeebeeBilling::Application.routes.draw do

  resources :business_users do
    member do
      get "external_url" => redirect("http://www.google.com")
    end
  end
end

Запуск этой спецификации дает следующие результаты:   Неудачи:

  1) BusinessUsersController routing routes to some external url
     Failure/Error: assert_routing "/business_users/7/external_url", "http://www.google.com"
     ActionController::RoutingError:
       No route matches "/business_users/7/external_url"
     # ./spec/routing/business_users_routing_spec.rb:19:in `block (3 levels) in <top (required)>'

Я не смог найти кого-либо, сообщающего об этой конкретной проблеме в любом месте.

Добавлена ​​подробная информация: маршрут успешно разрешен при проверке вручную.

4b9b3361

Ответ 1

Спецификации/тесты маршрутизации специализируются на проверке того, сопоставляется ли маршрут конкретному контроллеру и действию (и, возможно, некоторые параметры тоже).

Я ворвался во внутренние части Rails и Journey. RSpec и Rails (в основном, некоторые детали не учтены) используют Rails.application.routes.recognize_path для ответа на вопрос "это маршрутизируемое?"

Например:

$ rails console
> Rails.application.routes.recognize_path("/business_users/1", method: "GET")
 => {:action=>"show", :controller=>"business_users", :id=>"1"}

Однако на другом конце /business_users/1/external_url нет контроллера. Фактически, для выполнения перенаправления Rails создал экземпляр ActionDispatch::Routing::Redirect, который представляет собой небольшое приложение Rack. Контроллер Rails никогда не затрагивается. В основном вы устанавливаете другое приложение Rack для выполнения перенаправления.

Чтобы проверить перенаправление, я рекомендую вместо этого использовать спецификацию запроса (файл в spec/requests). Что-то вроде:

require "spec_helper"

describe "external redirection" do
  it "redirects to google.com" do
    get "/business_users/1/external_url"
    response.should redirect_to("http://www.google.com")
  end
end

Это проверяет маршрут неявно и позволяет вам протестировать перенаправление.

Ответ 2

Энди Линдеман имеет правильный ответ. Однако вам не нужно вводить спецификацию в spec/request, вы можете сохранить ее в spec/routing и быть явным с метаданными "type": describe 'my route', type: :request do

Ответ 3

Я столкнулся с аналогичным случаем, когда я пытался протестировать ряд маршрутов, некоторые из которых должны перенаправляться, а некоторые из них не должны. Я хотел сохранить их в одной спецификации маршрутизации, так как это был наиболее логичный способ их группировки.

Я попытался использовать describe: 'my route', type: request, но обнаружил, что не работает. Однако вы можете включить RSpec::Rails::RequestExampleGroup в контекст спецификации, чтобы получить доступ к методам спецификации запроса. Что-то вроде:

describe "My Routes" do
  context "Don't Redirect" do
    it "gets URL that doesn't redirect" do
      get("business_users/internal_url").should route_to(controller: "business_users", action: "internal_url_action")
    end
  end

  context "Redirection" do
    include RSpec::Rails::RequestExampleGroup
    it "redirects to google.com" do
      get "/business_users/1/external_url"
      response.should redirect_to("http://www.google.com")
    end
  end
end