【问题标题】:Rails: How to modify tests for a nested resource?Rails:如何修改嵌套资源的测试?
【发布时间】:2010-11-29 21:13:16
【问题描述】:

在学习 Rails 时,我创建了一个应用程序,其中包含一个嵌套在 Customers 控制器下方的 Domains 控制器。我正在使用 Rails 2.3.4,这是一次学习经历。我设法设置了以下路由:

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

但是,由于路由错误,域控制器的所有测试都失败了。

例如,以下测试(由 Rails 的资源生成器生成)失败,DomainsControllerTest 类中的所有其他测试也是如此。

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。我花了一个下午寻找所需的更改,但几乎每个站点都在谈论 Rspec 测试而不是常规 Rails 测试。

如何修改domains_controller_test.rb 使其能够理解嵌套资源?

【问题讨论】:

    标签: ruby-on-rails routing nested testing


    【解决方案1】:

    将 customer_id 与请求一起传递就可以了。像这样的东西:-

    类 DomainsControllerTest 1 断言响应:成功 assert_not_nil 分配(:域) 结尾 结尾

    【讨论】:

    • 这似乎行得通,Rishav。有没有办法把它干掉,而不是将 id 传递给每个单独的测试?
    • Martijn,这就是你必须要做的。您的路由必须知道客户才能工作。我想您可以编写一个测试助手来替换自动填充哈希的 customer_id 部分的“get”调用,但这似乎是个坏主意,除非您针对 DomainsController 编写很多很多测试。
    • 只是想指出为什么将其干燥可能是一个坏主意,因为它可能难以阅读和调试。 DRY 代码很棒,但在牺牲可读性时就不行了。在测试中,您肯定希望能够看到发生了什么。如果你可以在不牺牲可读性或增加测试脆弱性的情况下干掉它,那就去做吧。
    【解决方案2】:

    根据您的路线,域不再存在于客户环境之外。该请求需要 customer_id 来匹配命名路由。

    在您的测试中执行此操作的方法是:

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

    【讨论】:

    • 我不确定我是否理解问题所在。创建的域将是post :create, :customer_id=&gt;joecustomer_id 仍会在嵌套资源的 URL 中找到。
    【解决方案3】:

    有一个名为 nester 的 gem 可以解决这个确切的问题。它生成的方法可以返回domains_path 和类似的方法,就好像您的路线没有嵌套一样。当您的视图和测试引用例如domain_path(domain) 时,路由将扩展为customer_domain_path(domain.customer, domain)。还有一个ActionController::TestCase 帮助器,它为getpost 等方法添加了:customer_id =&gt; @domain.customer

    默认生成的功能测试和视图使用这种方法开箱即用。 (免责声明:我写的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      相关资源
      最近更新 更多