2009-09-20 8 views
34

Podczas nauki Railsów utworzyłem aplikację z kontrolerem Domains zagnieżdżoną pod kontrolerem Customers. Używam Rails 2.3.4 i to była nauka. Udało mi się uzyskać poniższe ustawienia routingu:Szyny: Jak zmodyfikować testy dla zagnieżdżonego zasobu?

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"} 

Jednak wszystkie testy kontrolera Domeny ulegają awarii z powodu błędów routingu.

Na przykład następujący test (wygenerowany przez generator zasobów Rails) nie powiedzie się, tak jak wszystkie inne testy w klasie DomainsControllerTest.

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

To nie z błędem:

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

Ma to sens, ponieważ trasy domyślne już nie istnieje, a kontroler domeny wymaga @customer być ustawiony. Spędziłem popołudnie szukając potrzebnej zmiany, ale prawie każda strona mówi o testach Rspec zamiast standardowych testów Rails.

Jak zmodyfikować domains_controller_test.rb, aby mógł zrozumieć zagnieżdżony zasób?

Odpowiedz

47

Przekazywanie identyfikatora customer_id z żądaniami będzie możliwe. Coś w tym stylu: -

 
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

To wydaje się działać, Rishav. Czy jest jakiś sposób, aby to WYTRZYMAĆ, zamiast przekazywać identyfikator do każdego osobnego testu? –

+1

Martijn, właśnie to musisz zrobić. Twoja trasa musi znać klienta do pracy. Przypuszczam, że mógłbyś napisać pomocnika testowego, który zastąpiłby wywołanie "get", które automatycznie uzupełni część hash client_id, ale to wygląda na zły pomysł, chyba że piszesz wiele, wiele testów przeciwko DomainsController. –

+1

Chcę tylko wskazać, dlaczego wysuszenie tego może być złym pomysłem b/c może być trudne do odczytania i debugowania. Kod DRY jest świetny, ale nie wtedy, gdy poświęca czytelność. W teście na pewno chcesz zobaczyć, co się dzieje. Jeśli możesz go osuszyć bez utraty czytelności lub dodania kruchości do testu, zrób to. – WattsInABox

1

Zgodnie z trasami domeny nie istnieją już poza kontekstem klienta. Żądanie musi być zgodne z customer_id dla nazwanych tras.

Sposób to zrobić w swoim teście to:

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

Bo działa, ale dla postu nie działa. –

+0

tak, jak rozwiązać ten problem dla postu? –

+0

+1 za sposób, w jaki można to zrobić za pomocą posta – Bastes

1

Jest to klejnot zwany nester że dokładnie rozwiązuje ten problem. Generuje on metody, które dają ci odpowiedź domains_path i podobne, jakby twoje trasy nie były zagnieżdżone. Kiedy twoje widoki i testy odnoszą się, na przykład, do domain_path(domain), trasy są rozszerzane do customer_domain_path(domain.customer, domain). Istnieje również ActionController::TestCase pomocnik, który dodaje :customer_id => @domain.customer metod takich jak get, post itp

Domyślna wygenerowana testy funkcjonalne i poglądy pracy po wyjęciu z pudełka z tym podejściem. (Zrzeczenie się: napisałem to).

Powiązane problemy