【问题标题】:Why are tests failing in Ruby on Rails?为什么在 Ruby on Rails 中测试会失败?
【发布时间】:2021-10-11 04:48:04
【问题描述】:

我正在研究“使用 Rails 4 进行敏捷 Web 开发”一书。其中,在与测试相关的某一时刻,它给出了两个错误

Error:
ProductsControllerTest#test_should_update_product:
ArgumentError: unknown keywords: :id, :product
    test/controllers/products_controller_test.rb:42:in `block in <class:ProductsControllerTest>'

Error:
ProductsControllerTest#test_should_create_product:
ArgumentError: unknown keyword: :product
    test/controllers/products_controller_test.rb:26:in `block (2 levels) in <class:ProductsControllerTest>'
    test/controllers/products_controller_test.rb:25:in `block in <class:ProductsControllerTest>'

在同一个地方,作者指出如何修复它们:在'setup do'中添加

@update = {
title: 'Lorem Ipsum',
description: 'Wibbles are fun!',
image_url: 'lorem.jpg',
price: 19.95
}

在“should_create_product”替换

post products_url, params: { product: { description: @product.description, image_url: @product.image_url, price: @product.price, title: @product.title } }

post :create, product: @update

并在 'should_update_product' 替换

patch product_url(@product), params: { product: { description: @product.description, image_url: @product.image_url, price: @product.price, title: @product.title } }

patch :update, id: @product, product: @update

但是,在这些修复之后,测试继续给出相同的错误。如何解决?

编辑: 我试图替换为

post :create, params: { product: @update }

patch :update, params: { id: @product, product: @update }

现在它给了我另一个错误:

Error:
ProductsControllerTest#test_should_create_product:
URI::InvalidURIError: bad URI(is not URI?): "http://www.example.com:80create"
    test/controllers/products_controller_test.rb:26:in `block (2 levels) in <class:ProductsControllerTest>'
    test/controllers/products_controller_test.rb:25:in `block in <class:ProductsControllerTest>'

Error:
ProductsControllerTest#test_should_update_product:
URI::InvalidURIError: bad URI(is not URI?): "http://www.example.com:80update"
    test/controllers/products_controller_test.rb:42:in `block in <class:ProductsControllerTest>'

【问题讨论】:

  • 你在哪个版本的rails上?这些错误来自 R5 及更高版本,而您的书适用于 R4。 patch :update, params: { id: @product, product: @update } 应该在 R5 中修复。
  • 我的 Rails 版本是 6.1.4.1。我按你说的换了,现在又给我一个错误
  • patch "/update", params: { id: @product, product: @update }
  • Error: ProductsControllerTest#test_should_create_product: ActionController::RoutingError: No route matches [POST] "/create" test/controllers/products_controller_test.rb:26:in block(2 个级别)在 ' test/controllers/products_controller_test.rb:25:in block in &lt;class:ProductsControllerTest&gt;' Error: ProductsControllerTest#test_should_update_product: ActionController::RoutingError: No route matches [PATCH] "/update" test/controllers/products_controller_test.rb:42:in block 在 '`
  • 您的网址中的路径似乎不正确example.com:80create。它可能应该是这样的:example.com:80/products/create。还有example.com:80updateexample.com:80/products/update

标签: ruby-on-rails testing


【解决方案1】:

您混淆了两种不同的测试。

第一个是ActionController::TestCase 形式的功能控制器测试,您的书中可能有它。这些是创建模拟请求对象并将其传递给控制器​​实例的测试。在遗留应用程序之外非常不鼓励使用这些,因为它们往往会让大量错误通过。在功能测试中你会写 post :create, params: { product: { ... }} 因为你实际上是在控制器实例上调用 create 方法。

第二个是ActionDispatch::IntegrationTest 形式的集成测试,您可以在其中向您的Rails 应用程序发送实际的HTTP 请求。这是现代方法,它与现代版本的 Rails 中的功能测试一样快,而本书编写时并非如此。

在集成测试中,您传递路径或 url:

post '/products', params: { product: ... }

第二个问题是在 Rails 5 中引入的强制性关键字参数。

在以前的 Rails 版本中,您可以调用:

get '/foo', bar: 1, baz: 2

Rails 会将任何未知的键(不是参数、标题、格式等)视为参数,这是许多错误的根源。在 Rails 5+ 中,您明确需要在 params 选项中传递参数。

get '/foo', params: { bar: 1, baz: 2 }

我建议你用一些更现代的资源来补充这本书,或者获得一个更新的版本,因为自 Rails 4 以来发生了很多变化,并且在阅读 Rails 6 中的旧书将会很痛苦。

【讨论】:

    猜你喜欢
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多