rails example databasecleaner ruby-on-rails ruby-on-rails-3 rspec2

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.



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.