2009-09-20 11 views
34

Mientras aprendía Rails, he creado una aplicación con un controlador Domains anidado debajo de un controlador Customers. Estoy usando Rails 2.3.4 y ha sido una experiencia de aprendizaje. Me las arreglé para obtener la siguiente configuración de enrutamiento:Rieles: ¿cómo modificar las pruebas de un recurso anidado?

customer_domains GET /customers/:customer_id/domains(.:format)   {:controller=>"domains", :action=>"index"} 
        POST /customers/:customer_id/domains(.:format)   {:controller=>"domains", :action=>"create"} 
new_customer_domain GET /customers/:customer_id/domains/new(.:format)  {:controller=>"domains", :action=>"new"} 
edit_customer_domain GET /customers/:customer_id/domains/:id/edit(.:format) {:controller=>"domains", :action=>"edit"} 
    customer_domain GET /customers/:customer_id/domains/:id(.:format)  {:controller=>"domains", :action=>"show"} 
        PUT /customers/:customer_id/domains/:id(.:format)  {:controller=>"domains", :action=>"update"} 
        DELETE /customers/:customer_id/domains/:id(.:format)  {:controller=>"domains", :action=>"destroy"} 
      customers GET /customers(.:format)        {:controller=>"customers", :action=>"index"} 
        POST /customers(.:format)        {:controller=>"customers", :action=>"create"} 
     new_customer GET /customers/new(.:format)       {:controller=>"customers", :action=>"new"} 
     edit_customer GET /customers/:id/edit(.:format)      {:controller=>"customers", :action=>"edit"} 
      customer GET /customers/:id(.:format)       {:controller=>"customers", :action=>"show"} 
        PUT /customers/:id(.:format)       {:controller=>"customers", :action=>"update"} 
        DELETE /customers/:id(.:format)       {:controller=>"customers", :action=>"destroy"} 
       root  /            {:controller=>"customers", :action=>"index"} 

Sin embargo, todas las pruebas para el controlador de dominios están fallando debido a errores de enrutamiento.

Por ejemplo, la siguiente prueba (generada por el generador de recursos de Rails) falla, al igual que todas las demás pruebas en la clase DomainsControllerTest.

class DomainsControllerTest < ActionController::TestCase 
    test "should get index" do 
    get :index 
    assert_response :success 
    assert_not_nil assigns(:domains) 
    end 
end 

falla con el error:

No route matches {:action => "index", :controller => "domains"} 

Esto tiene sentido ya que las rutas por defecto ya no existen y el controlador de Dominios requiere un @customer a establecer. Pasé una tarde buscando el cambio necesario, pero casi todos los sitios hablan de pruebas de Rspec en lugar de las pruebas normales de Rails.

¿Cómo modifico el domains_controller_test.rb para que entienda el recurso anidado?

Respuesta

47

Pasar el id_cliente con las solicitudes sería suficiente. Algo como esto: -

 
class DomainsControllerTest < ActionController::TestCase 
    test "should get index" do 
    get :index ,:customer_id=> 1 
    assert_response :success 
    assert_not_nil assigns(:domains) 
    end 
end 
+0

Eso parece funcionar, Rishav. ¿Hay alguna forma de SECAR esto, en lugar de pasar el ID a cada prueba por separado? –

+1

Martijn, eso es lo que vas a tener que hacer. Su ruta debe saber que el cliente debe trabajar. Supongo que podría escribir un asistente de prueba para reemplazar la llamada "obtener" que autocompleta la parte customer_id del hash, pero parece una mala idea, a menos que esté escribiendo muchas, muchas pruebas en contra de DomainsController. –

+1

Solo quiero señalar por qué DRYing esto podría ser una mala idea, porque podría ser difícil de leer y depurar. El código DRY es genial, pero no cuando sacrifica la legibilidad. En una prueba, definitivamente quiere poder ver lo que está pasando. Si puedes DIVIDIRLO sin sacrificar la legibilidad o agregar fragilidad a la prueba, hazlo. – WattsInABox

1

Según sus rutas, los dominios ya no existen fuera del contexto de un cliente. La solicitud necesita un customer_id para que las rutas nombradas coincidan.

La manera de hacer esto en su prueba es:

test "should get index" do 
    get :index, :customer_id=>joe 
end 
+4

Para que funcione, pero para publicar no parece funcionar. –

+0

yup, ¿cómo resuelves este problema para publicarlo? –

+0

+1 de cómo puedes hacerlo con una publicación – Bastes

1

Hay una gema llamada nester que resuelve este problema exacto. Genera métodos que le devuelven un domains_path y similares como si sus rutas no estuvieran anidadas. Cuando sus vistas y pruebas hacen referencia, por ejemplo, domain_path(domain), las rutas se expanden a customer_domain_path(domain.customer, domain). También hay un ayudante ActionController::TestCase que añade :customer_id => @domain.customer de métodos como get, post, etc.

El valor por defecto genera pruebas funcionales y puntos de vista trabajan fuera de la caja con este enfoque. (Descargo de responsabilidad: lo escribí).

Cuestiones relacionadas