2009-09-20 11 views
34

Railsを学んでいる間に、DomainsコントローラをCustomersコントローラの下にネストしたアプリケーションを作成しました。私はRails 2.3.4を使用しています。それは学習の経験です。Rails:ネストされたリソースのテストを変更するにはどうすればよいですか?

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

ただし、ルーティングエラーのためにドメインコントローラのすべてのテストに失敗しています。

たとえば、DomainsControllerTestクラスの他のすべてのテストと同様に、次のテスト(Railsのリソースジェネレータで生成)は失敗します。

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

それはエラーで失敗します。

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

デフォルトルートは、もはや存在して以来、これは理にかなっていないとドメインコントローラが設定する@customerが必要です。午後、必要な変更を探していましたが、ほとんどすべてのサイトで通常のRailsテストではなくRspecテストについて話しています。

domains_controller_test.rbを変更してネストされたリソースを理解するにはどうすればよいですか?

答えて

47

リクエストにcustomer_idを渡すことができます。 -

 
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

それはうまくいくようです、リシャブ。それぞれ別のテストにIDを渡す代わりに、これをDRYする方法はありますか? –

+1

Martijn、それはあなたがしなければならないことです。ルーティングでは、顧客が作業することを知っていなければなりません。私はあなたがハッシュのcustomer_id部分をオートフィルする "get"呼び出しを置き換えるテストヘルパを書くことができると思いますが、DomainsControllerに対する多くのテストを書かない限り、それは悪い考えです。 –

+1

これをDRYすることが悪い考えである理由を指摘したいのですが、読み込みとデバッグが困難な場合があります。 DRYコードは大丈夫ですが、読みやすさを犠牲にしているわけではありません。テストでは、あなたは何が起こっているのかを確かに見ることができるようにしたいと思っています。可読性を犠牲にすることなく、またはテストに脆弱性を追加することなくDRYを行うことができれば、それを実行してください。 – WattsInABox

1

あなたのルートによれば、ドメインは顧客のコンテキストの外には存在しません。名前付きルートが一致するには、要求にcustomer_idが必要です。

テストでこれを行う方法は次のとおりです。

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

それは動作するが、ポストのために動作していないようです。 –

+0

ええ、投稿のためにこの問題をどうやって解決しますか? –

+0

投稿でどうすればいいですか? – Bastes

1

この正確な問題を解決しnesterと呼ばれる宝石があります。あなたのルートがネストされていないかのようにdomains_pathのようなものを返すメソッドを生成します。ビューとテストが参照する場合、たとえばdomain_path(domain)の場合、ルートはcustomer_domain_path(domain.customer, domain)に展開されます。デフォルトでは、機能テストとビューは、このアプローチに箱から出して動作し、生成

getpostようなメソッドのため:customer_id => @domain.customerを追加ActionController::TestCaseヘルパーは、などもあります。 (免責事項:私はそれを書いた)。

関連する問題