【问题标题】:How to test a nested resource's controller with Rspec?如何使用 Rspec 测试嵌套资源的控制器?
【发布时间】:2012-02-10 02:32:54
【问题描述】:

我的嵌套资源在模型和 routes.rb 中关联:

resources :foos do
  resources :bars
end

我的应用路由正常,但我似乎无法证明关于我的嵌套路由的任何断言:

describe BarsController do

it "should have a route to 'show'" do
  assert_generates "/foos/bars/1", 
                   {controller: :bars, action: :show, id: "1"}
end

这是错误:

Failure/Error: assert_generates "/foos/bars/1",
ActionController::RoutingError:
No route matches {:controller=>"bars", :action=>"show", :id=>"1"}

如何测试这些嵌套路由?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 rspec rspec2


    【解决方案1】:

    您可以将assert_generatesassert_recognizesassert_routing 用于testing routes。例如,

    assert_generates "/foo/bar/1", 
         { :controller => "bar", :action => "show", :id => "1" }
    

    【讨论】:

    • 感谢 nkm 提供的有用技巧。但是对于嵌套路由,我似乎仍然无法使该断言成立。以上编辑。
    • 在上面的代码中,{controller: :bars, action: :show, id: "1"} 看起来像 javascript 方式,在 ruby​​ 中是 {controller => :bars, action => :show, id => "1"}。但是从错误消息中说没有匹配的路线。请确认已经使用rake routes命令定义了对应的路由。
    • @nkm 你所说的“javascript方式”也可以称为Ruby 1.9方式。它们是等价的:{ :one => 123 }{ one: 123 }
    • 你是对的@Rob Davis,我没有意识到这一点。感谢您的更新(+1) :)
    【解决方案2】:

    当您运行 rake routes 时,您应该会看到您的嵌套路由如下所示:

    foo_bar GET    /foos/:foo_id/bars/:id(.:format)      bars#show
    

    所以需要两个参数来匹配这条路由:foo_idid。由于您只提供id,因此无法找到路线。

    此外,对于在 rspec 中测试路由,您可能会发现使用内置的 routes_to 匹配器比回退到 assert_* 更有用,如下所示:

    it "routes to the 'show' action" do
      { get: "/foos/123/bars/456" }.
        should route_to controller: "bars",
          action: "show",
          foo_id: "123",
          id: "456"
    end
    

    【讨论】:

    • 我看到有人否决了这个答案,但没有发表评论说明原因。也许是因为自 2012 年 2 月编写此答案时 rspec 语法发生了变化,但谁能说呢?
    猜你喜欢
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    相关资源
    最近更新 更多