ruby-on-rails - example - ruby capybara github
Cómo probar rutas en un motor montable Rails 3.1 (6)
Basándome en this respuesta elegí la siguiente solución:
#spec/spec_helper.rb
RSpec.configure do |config|
# other code
config.before(:each) { @routes = MyEngine::Engine.routes }
end
El beneficio adicional es que no necesita tener el bloque before(:each)
en cada especificación de controlador.
Estoy intentando escribir algunas especificaciones de enrutamiento para un motor de rieles 3.1 montables. Tengo especificaciones de modelo y controlador de trabajo, pero no puedo averiguar cómo especificar rutas.
Para un motor de muestra, ''testy'', cada enfoque que intento termina con el mismo error:
ActionController::RoutingError: No route matches "/testy"
He probado la sintaxis de Rspec y Test :: Unit (spec / routing / index_routing_spec.rb):
describe "test controller routing" do
it "Routs the root to the test controller''s index action" do
{ :get => ''/testy/'' }.should route_to(:controller => ''test'', :action => ''index'')
end
it "tries the same thing using Test::Unit syntax" do
assert_routing({:method => :get, :path => ''/testy/'', :use_route => :testy}, {:controller => ''test'', :action => ''index''})
end
end
He trazado las rutas correctamente (config / route.rb):
Testy::Engine.routes.draw do
root :to => ''test#index''
end
Y los montó en la aplicación ficticia (spec / dummy / config / route.rb):
Rails.application.routes.draw do
mount Testy::Engine => "/testy"
end
Y ejecutando el rails server
y solicitando http://localhost:3000/testy/
funciona bien.
¿Me estoy perdiendo algo obvio, o es que todavía no está bien insertado en el marco?
Actualización: como @andrerobot señala, la gente de rspec ha solucionado este problema en la versión 2.14, así que he cambiado mi respuesta aceptada en consecuencia.
Desde RSpec 2.14 puedes usar lo siguiente:
describe "test controller routing" do
routes { Testy::Engine.routes }
# ...
end
Esto funcionó para mí:
# spec_helper.rb
RSpec.configure do |config|
config.include MyEngine::Engine.routes.url_helpers
end
Intente agregar un bloque anterior con lo siguiente:
before(:each) { @routes = Testy::Engine.routes }
Eso me funcionó, ya que las especificaciones de enrutamiento usan esa variable de instancia de nivel superior para probar sus rutas.
La respuesta de Steven Anderson me llevó casi todo el camino hasta allí, pero las solicitudes deben hacerse en relación con el motor, en lugar de la aplicación, probablemente porque esta técnica reemplaza las rutas de la aplicación con las rutas del motor, por lo que todo es ahora relativo a la motor. Me parece un poco frágil, pero no he visto otra manera que funcione. Si alguien publica una forma más limpia de hacer esto, estaré encantado de aceptar esa respuesta.
En la aplicación ''dummy'', si el motor está montado de la siguiente manera (spec / dummy / config / route.rb):
Rails.application.routes.draw do
mount Testy::Engine => "/testy"
end
La siguiente especificación probará correctamente la ruta raíz del motor usando tanto la sintaxis rspec como la prueba :: unit (spec / routing / index_route_spec.rb):
require ''spec_helper''
describe "test controller routing" do
before(:each) { @routes = Testy::Engine.routes }
it "Routes the root to the test controller''s index action" do
{ :get => ''/'' }.should route_to(:controller => ''testy/test'', :action => ''index'')
end
it "tries the same thing using Test::Unit syntax" do
assert_routing({:method => :get, :path => ''/''}, {:controller => ''testy/test'', :action => ''index''})
end
end
Para mí, fue una combinación de comentarios de casi todos los involucrados hasta ahora.
Primero, comencé con esta simple prueba:
it "routes / to the widgets controller" do
get(''/'').should route_to("mozoo/widget#index")
end
Esto resultó en:
Failures:
1) Mozoo::WidgetController GET widget index routes / to the widgets controller
Failure/Error: get(''/'').should route_to("mozoo/widget#index")
ActionController::RoutingError:
No route matches {:controller=>"mozoo/widget", :action=>"/"}
# ./spec/controllers/mozoo/widget_controller_spec.rb:9:in `block (3 levels) in <module:Mozoo>''
Así que cambié de get(''/'')
a { :get => ''/'' }
y las cosas empezaron a funcionar muy bien. No estoy seguro de por qué. De acuerdo con lib / rspec / rails / matchers / routing_matchers.rb L102-105 , no hay diferencia, pero para mí es una diferencia. En cualquier caso, gracias @ cameron-papa.
A continuación, agregué otra prueba bastante simple y muy similar a la anterior:
it "routes root_path to the widgets controller" do
{ :get => root_path }.should route_to("mozoo/widget#index")
end
Y estaba recibiendo este error:
Failures:
1) Mozoo::WidgetController GET widget index routes root_path to the widgets controller
Failure/Error: { :get => ''/mozoo'' }.should route_to("mozoo/widget#index")
No route matches "/mozoo"
# ./spec/controllers/mozoo/widget_controller_spec.rb:14:in `block (3 levels) in <module:Mozoo>''
Así que agregué esto:
before(:each) { @routes = Mozoo::Engine.routes }
Y consiguió un error mejor / diferente:
Failures:
1) Mozoo::WidgetController GET widget index routes root_path to the widgets controller
Failure/Error: { :get => root_path }.should route_to("mozoo/widget#index")
The recognized options <{"controller"=>"mozoo/widget", "action"=>"index", "section"=>"mozoo"}> did not match <{"controller"=>"mozoo/widget", "action"=>"index"}>, difference: <{"section"=>"mozoo"}>.
<{"controller"=>"mozoo/widget", "action"=>"index"}> expected but was
<{"controller"=>"mozoo/widget", "action"=>"index", "section"=>"mozoo"}>.
# ./spec/controllers/mozoo/widget_controller_spec.rb:14:in `block (3 levels) in <module:Mozoo>''
Desde allí, cambié mi prueba para incluir la sección (el espacio de nombres donde se encuentra mi motor):
{ :get => root_path }.should route_to(:controller => "mozoo/widget", :action => "index", :section => "mozoo")
Y viola, pasó. Gracias @ Steven-Anderson.
La siguiente parte es impar. Después de agregar otra prueba para un widget específico que usó el ayudante url widget_path para una ruta con nombre:
it "will successfully serve the widget show page" do
visit widget_path(:foobar)
response.should be_success
end
La prueba rápidamente explotó en mí con:
Failures:
1) GET bubble_summary_row widget will have the content section properly scoped
Failure/Error: visit widget_path(:bubble_summary_row)
NoMethodError:
undefined method `widget_path'' for #<RSpec::Core::ExampleGroup::Nested_3:0x0000010748f618>
# ./spec/views/mozoo/widgets/show.html.haml_spec.rb:7:in `block (2 levels) in <module:Mozoo>''
Así que agregué la siguiente entrada de configuración de spec_helper:
RSpec.configure do |config|
config.include Testy::Engine.routes.url_helpers
end
Y BAM! Pasó. Gracias @ sam-soffes. Lo que hace esto extraño es que más adelante, al crear este comentario, eliminé esa entrada de configuración para intentar recuperar el error y no pude reproducir el error simplemente eliminando la entrada de configuración. Oh bueno, me voy a mover. Esperemos que esta larga cuenta ayude a alguien.