Нужны ли маршруты маршрутизации для перенаправления маршрутов? [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)>'
Я не смог найти кого-либо, сообщающего об этой конкретной проблеме в любом месте.
Добавлена подробная информация: маршрут успешно разрешен при проверке вручную.
Ответы
Ответ 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
Ответ 4
Я думаю, вы хотите redirect_to matcher.