gpt4 book ai didi

ruby-on-rails - Rails 功能测试 : sending URL query parameters in POST request

转载 作者:行者123 更新时间:2023-12-04 01:33:38 25 4
gpt4 key购买 nike

我在 Rails 功能测试中发送一个 POST 请求,如下所示:

post :create, collection: { name: 'New Collection' }
collection正如预期的那样,作为 JSON 编码的表单数据发送。

我不知道如何向 URL 添加查询。 The documentation说我可以访问请求对象并在它被发送之前修改它。所以我试过这个:
@request.GET[:api_key] = 'my key'
post :create, collection: { name: 'New Collection' }

但是, :api_key从未出现在 request.GET服务器上的哈希。 (不过,当我通过另一个 HTTP 客户端发送它时。)

最佳答案

首先要澄清一些背景知识:虽然请求不能同时是 GET 和 POST,但存在 nothing stopping您在使用 POST 时同时使用查询字符串和正文表单数据。您甚至可以使用查询字符串中的所有参数进行 POST and an empty body ,虽然这听起来很不寻常。

Rails 支持这种情况,实际上您可以使用 POST 请求轻松发送表单,并且仍然可以在表单的操作中进行查询。该查询可以通过 request.GET hash 访问(这是 query_string 的别名),而 POST 主体参数与 request.POST hash (别名 request_parameters )。 params hash 实际上是从 combined GET and POST hashes 构造的.

然而,从我的研究看来, Rails 不支持在功能 Controller 测试中的 POST 请求中传递查询字符串 .尽管我在任何文档或 known issues on github 中都找不到任何关于此的信息。 ,源代码很清楚。在下面的文本中,我假设您使用 Rails 4。

为什么它不起作用

功能 Controller 测试的问题在于它们不使用真实的请求/响应,而是模拟 HTTP 握手:请求被模拟,其参数填充在适当的位置,并且给定的 Controller 操作只是作为普通的 ruby​​ 方法被调用。所有这些都在 action_controller/test_case classes 中完成.

事实证明,由于两个原因,此模拟在您的特定情况下不起作用:

  • 运行测试时传入的参数为总是 handed over 要么 request_parameters ,即 request.POST使用 post 时的哈希值请求 query_string (即 request.GET )用于 get测试请求。在一次测试运行期间无法同时设置这两个哈希值。

    这实际上是有道理的,因为 get , post等功能测试中的助手仅接受单个散列参数,因此内部测试代码无法知道如何将它们分成两个散列。
  • 确实可以在使用 @request 运行测试之前设置请求。变量,但只能在一定程度上,例如,您可以设置标题。但是您无法设置请求的内部属性 , 因为 它们被回收在试运行期间。回收完成here并重置请求对象和底层机架请求对象的所有内部变量。因此,如果您尝试像这样设置请求 GET 参数 @request.GET[:api_key] = 'my key' ,它不会有任何影响,因为表示此散列的内部变量将在回收期间被删除。

  • 解决方案/变通方法
  • 放弃功能测试和改为选择集成测试 .集成测试 allow to set the rack environment variables与主要参数分开。以下集成测试通过了 QUERY_STRING除了正常的 post body 参数之外,rack env 变量应该可以完美地工作:
    class CollectionsTest < ActionDispatch::IntegrationTest
    test 'foo' do
    post collections_path, { collection: { name: 'New Collection' } },
    { "QUERY_STRING" => "api_key=my_api_key" }

    # this proves that the parameters are recognized separately in the controller
    # (you can test this in you controller as well as here in the test):
    puts request.POST.inspect
    # => {"collection"=>{"name"=>"New Collection"}}
    puts request.GET.inspect
    # => {"api_key"=>"my_api_key"}
    end
    end

    您仍然可以在集成测试中使用功能测试中的大部分功能。例如您可以使用 assigns 测试 Controller 中分配的实例变量哈希。

    的事实也支持过渡论点。 Rails 5 将 deprecate支持集成测试的功能 Controller 测试 从 Rails 5.1 开始,这些功能测试支持将移到单独的 gem 中。
  • 尝试 Rails 5:虽然功能测试将被弃用,但它的源代码似乎是 heavily rewritten在 rails master 中,例如不再使用请求的回收。因此,您可以尝试并尝试在测试设置期间设置请求的内部变量。不过我还没有测试过。
  • 当然,您总是可以尝试修补功能测试,使其支持 query_string 的单独参数。和 request_parameters要在测试中定义的散列。

  • 我会走集成测试路线:)。

    关于ruby-on-rails - Rails 功能测试 : sending URL query parameters in POST request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24209915/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com