2011-10-07 11 views
18

Estoy tratando de escribir algunas especificaciones de enrutamiento para un motor de raíles montables 3.1. Tengo especificaciones de modelo y controlador de trabajo, pero no puedo encontrar la manera de especificar rutas.Cómo probar rutas en un motor montable Rails 3.1

Para un motor de la muestra, 'irritable', todos los enfoques que intento extremos con el mismo error:

ActionController::RoutingError: 
    No route matches "/testy" 

He intentado tanto la sintaxis Unidad Rspec y Test :: (espec/enrutamiento/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 presentado las rutas correctamente (config/routes.rb):

Testy::Engine.routes.draw do 
    root :to => 'test#index' 
end 

y les monté en la aplicación ficticia (spec/maniquí/config/routes.rb):

Rails.application.routes.draw do 
    mount Testy::Engine => "/testy" 
end 

Y corriendo rails server y solicitando http://localhost:3000/testy/ funciona bien.

¿Me falta algo obvio, o esto todavía no está bien cocido en el marco todavía?

Actualización: Como señala @andrerobot, la gente de rspec ha solucionado este problema en la versión 2.14, así que he cambiado mi respuesta aceptada en consecuencia.

+0

ve usted la ruta cuando se ejecuta rutas rastrillo? –

+0

¿Tiene usted requiere 'spec_helper' en index_routing_spec.rb? – squarism

+0

rutas de rastrillo no funciona en los motores de rieles 3.1.Tal vez sea un error pero se explica aquí: http://stackoverflow.com/questions/7431687/listing-rake-routes-for-a-mountable-rails-3-1-engine –

Respuesta

11

Desde RSpec 2.14 se puede utilizar lo siguiente:

describe "test controller routing" do 
    routes { Testy::Engine.routes } 
    # ... 
end 

Fuente: https://github.com/rspec/rspec-rails/pull/668

+0

¡Gracias por la actualización! He creado un motor puede montar utilizando rspec 2.14 y 4.0 carriles, y que funcionó como un encanto. Cambié mi respuesta aceptada. –

+1

¿Qué sucede si necesito tanto las rutas desde el motor como las rutas desde main_app? – Jwan622

10

trate de añadir un bloque de antes con lo siguiente:

before(:each) { @routes = Testy::Engine.routes } 

que trabajó para mí, ya que las especificaciones técnicas de enrutamiento utilizan esa variable de instancia de nivel superior para poner a prueba sus rutas.

+0

Gracias - eso estuvo muy cerca, pero reemplazar las rutas 'predeterminadas' con las rutas del motor también me obligó a cambiar mis pruebas, así que cambié la respuesta porque era la última pista que necesitaba . Desafortunadamente –

4

Esto funcionó para mí:

# spec_helper.rb 
RSpec.configure do |config| 
    config.include MyEngine::Engine.routes.url_helpers 
end 
+0

incluyendo los ayudantes de URL no cambiaron el error que estaba viendo: ActionController :: RoutingError: No hay ninguna ruta "/" irritables –

11

La respuesta de Steven Anderson me mayor parte del camino no tiene, pero necesita las solicitudes que hacerse con respecto al 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 ahora todo está relacionado con el motor. Me parece un poco frágil, pero no he visto otra manera de que funcione. Si alguien publica una forma más limpia de hacerlo, me complacerá aceptar esa respuesta.

En la aplicación 'maniquí', si el motor se monta como sigue (spec/maniquí/config/routes.rb):

Rails.application.routes.draw do 
    mount Testy::Engine => "/testy" 
end 

La especificación siguiente probará correctamente la ruta raíz del motor usando tanto rspec y la sintaxis de prueba :: unidad (spec/enrutamiento/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 
+0

Este. Me gustaría ser capaz de usar algo como 'get: '/ irritable /'' en mi especificaciones para que coincida más estrechamente en realidad estoy montado el motor. Pero eso no parece posible y esta respuesta parece ser la mejor forma actual de obtener las especificaciones. – dojosto

+0

Esto funcionó para mí, pero para la prueba de la unidad I :: coloca la asignación @routes en mi función de configuración. – mkrinblk

1

Para mí, fue una combinación de los comentarios de casi todo el mundo implicado hasta ahora.

En primer lugar, empecé con esta sencilla prueba:

it "routes/to the widgets controller" do 
    get('/').should route_to("mozoo/widget#index") 
    end 

Esto dio lugar a:

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é get('/')-{ :get => '/' } y cosas empecé a trabajar muy bien. No estoy seguro por qué. De acuerdo con lib/rspec/rails/matchers/routing_matchers.rb L102-105, no hay diferencia, pero hace una diferencia para mí. De todos modos, gracias @ cameron-papa.

A continuación, añadió otra prueba muy 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 fue conseguir 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>' 

por lo que añade esto:

before(:each) { @routes = Mozoo::Engine.routes } 

Y obtuve 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>' 

A partir de ahí, he cambiado de prueba para incluir la sección (el espacio de nombres mi motor es bajo):

{ :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 añadir otra prueba para un widget específico que utiliza el ayudante widget_path url para una ruta denominada:

it "will successfully serve the widget show page" do 
    visit widget_path(:foobar) 
    response.should be_success 
    end 

La prueba blowd rápidamente arriba 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>' 

por lo que añade la entrada siguiente configuración spec_helper :

RSpec.configure do |config| 
    config.include Testy::Engine.routes.url_helpers 
end 

Y BAM! Pasó. Gracias @ sam-soffes. Lo que hace que esto sea 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 estoy moviendo. Afortunadamente, esta larga cuenta ayuda a alguien.

0

Basado en this respuesta que eligió 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 todas las especificaciones del controlador.

+1

Esto no funcionó para mí. ¿Alguna idea de por qué? Si agrego eso antes de la línea en la prueba en sí, parece que funciona. – Karan