Rails 3上嵌套路由的功能测试

Jef*_*gal 2 routing unit-testing ruby-on-rails ruby-on-rails-3

我有一个带有以下嵌套路由的Rails 3应用程序:

resources :games do
  collection do
    get :all
    get :unassigned
  end
  resources :messages
  resources :comments
end
Run Code Online (Sandbox Code Playgroud)

游戏有很多评论,游戏也有很多消息.

我期待"/ games/1/comments"路由到注释控制器上的索引操作,并设置:game_id => 1在params哈希中.

在应用程序中一切正常.但是,我的路线测试失败了,我无法弄清楚原因.

当我尝试这个:

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

我明白了:

  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}>
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时(注意引用:game_id):

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

我明白了:

  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 <{}>
Run Code Online (Sandbox Code Playgroud)

还试过这个:

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

响应:

The recognized options <{"action"=>"index", "game_id"=>"1", "controller"=>"messages"}> 
did not match <{"action"=>"index", "controller"=>"messages"}>, difference: <{"game_id"=>"1"}>
Run Code Online (Sandbox Code Playgroud)

我想,不知怎的,我已经挂断了在嵌套资源上测试路由的语法.有任何想法吗?

提前致谢 -

Mar*_*rth 5

断言路由做两件事(按此顺序)

  • assert_recognizes
  • assert_generates

因此,您的测试用例2更进一步/表现更好.

现在,assert_generates检查是否url_for返回你给它的url.

url_for(:controller => "messages", :action => "index", :game_id => "1")
# should return: /games/1/messages
Run Code Online (Sandbox Code Playgroud)

但根据例外,它返回/messages?game_id=1(game_id作为额外).这应该/只能发生,如果你有一个resources :messages规则之前resources :games.如果是这种情况,请将其移至后面,以便首先嵌套规则.