开发者

Functional tests of nested routes on Rails 3

I have a Rails 3 app with the following nested route:

resources :games do
  collection do
    get :all
    get :unassigned
  end
  resources :messages
  resources :comments
end

A Game has many comments, and a Game also has many messages.

I am expecting that "/games/1/comments" routes to the index action on the 开发者_StackOverflow社区comments controller, and sets :game_id => 1 in the params hash.

Everything is working fine in the app. However, my route tests are failing and I can't figure out why.

When I try this:

assert_routing({:path => "/games/1/messages", :method => :get},
  { :controller => "messages", :action => "index", :game_id => 1})

I get this:

  2) Failure:
test_route_one(MessagesControllerTest)
    [actionpack (3.0.3) lib/action_dispatch/testing/assertions/routing.rb:52:in `assert_recognizes'
     actionpack (3.0.3) lib/action_dispatch/testing/assertions/routing.rb:120:in `assert_routing'
     test/functional/messages_controller_test.rb:106:in `test_route_one'
     activesupport (3.0.3) lib/active_support/testing/setup_and_teardown.rb:67:in `__send__'
     activesupport (3.0.3) lib/active_support/testing/setup_and_teardown.rb:67:in `run'
     activesupport (3.0.3) lib/active_support/callbacks.rb:438:in `_run_setup_callbacks'
     activesupport (3.0.3) lib/active_support/testing/setup_and_teardown.rb:65:in `run']:
The recognized options <{"action"=>"index", "game_id"=>"1", "controller"=>"messages"}> 
did not match <{"action"=>"index", "game_id"=>1, "controller"=>"messages"}>, 
difference: <{"game_id"=>1}>

When I try this (note the quoting on :game_id) :

assert_routing({:path => "/games/1/messages", :method => :get},
  { :controller => "messages", :action => "index", :game_id => "1"})

I get this:

  3) Failure:
test_route_two(MessagesControllerTest)
    [actionpack (3.0.3) lib/action_dispatch/testing/assertions/routing.rb:90:in `assert_generates'
     actionpack (3.0.3) lib/action_dispatch/testing/assertions/routing.rb:127:in `assert_routing'
     test/functional/messages_controller_test.rb:111:in `test_route_two'
     activesupport (3.0.3) lib/active_support/testing/setup_and_teardown.rb:67:in `__send__'
     activesupport (3.0.3) lib/active_support/testing/setup_and_teardown.rb:67:in `run'
     activesupport (3.0.3) lib/active_support/callbacks.rb:438:in `_run_setup_callbacks'
     activesupport (3.0.3) lib/active_support/testing/setup_and_teardown.rb:65:in `run']:
found extras <{:game_id=>"1"}>, not <{}>

Also tried this:

assert_routing({:path => "/games/1/messages", :method => :get}, {:controller => "messages", :action => "index"}, {}, {:game_id => "1"})

Response:

The recognized options <{"action"=>"index", "game_id"=>"1", "controller"=>"messages"}> 
did not match <{"action"=>"index", "controller"=>"messages"}>, difference: <{"game_id"=>"1"}>

I think, somehow, I'm getting hung up on the syntax for testing the routing on nested resources. Any ideas?

Thanks in advance--


Assert routing does two things (in that order)

  • assert_recognizes
  • assert_generates

So your test-case 2 gets one step further / performs better.

Now, assert_generates checks whether url_for returns the url you give it.

url_for(:controller => "messages", :action => "index", :game_id => "1")
# should return: /games/1/messages

But according to the exception, it returns /messages?game_id=1 (game_id as the extra). This should/can only happen, if you have a resources :messages rule before your resources :games. If that's the case, move it behind, so that the nested rule comes first.


Try

assert_routing({:path => "/games/1/messages", :method => :get}, {:controller => "messages", :action => "index"}, {}, {:game_id => "1"})
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜