【问题标题】:Functional tests of nested routes on Rails 3Rails 3 上嵌套路由的功能测试
【发布时间】:2010-12-18 18:05:58
【问题描述】:

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

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

一个游戏有很多cmets,一个游戏也有很多消息。

我期待“/games/1/cmets”路由到 cmets 控制器上的索引操作,并在 params 哈希中设置 :game_id => 1

应用程序一切正常。但是,我的路线测试失败了,我不知道为什么。

当我尝试这个时:

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

我明白了:

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

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

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

我明白了:

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

也试过这个:

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

回复:

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

我想,不知何故,我对在嵌套资源上测试路由的语法感到困惑。有什么想法吗?

提前致谢--

【问题讨论】:

    标签: ruby-on-rails unit-testing routing ruby-on-rails-3


    【解决方案1】:

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

    • assert_recognizes
    • assert_generates

    所以你的测试用例 2 更进一步/表现更好。

    现在,assert_generates 检查url_for 是否返回您提供的网址。

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

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

    【讨论】:

    • 已确认。像一个老板一样。谢谢马塞尔!
    • 是的,我复制了 OP 的设置并在嵌套块之前添加了 resources :messages 并得到了同样的错误。很好的发现。
    • 是的,对我来说也是这样。非常感谢!
    【解决方案2】:

    试试

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多