【问题标题】:RSpec request spec post an empty arrayRSpec 请求规范发布一个空数组
【发布时间】:2018-07-18 07:36:21
【问题描述】:

我目前正在 Rails 中开发 API 端点。如果我需要的数据无效,我想确保端点响应具有正确的错误状态。我需要一个 id 数组。无效值之一是空数组。

有效

{ vendor_district_ids: [2, 4, 5, 6]}

无效

{ vendor_district_ids: []}

使用 RSpec 请求规范

所以我想要一个请求规范来控制我的行为。

require 'rails_helper'

RSpec.describe Api::PossibleAppointmentCountsController, type: :request do
  let(:api_auth_headers) do
    { 'Authorization' => 'Bearer this_is_a_test' }
  end

  describe 'POST /api/possible_appointments/counts' do
    subject(:post_request) do
      post api_my_controller_path,
        params: { vendor_district_ids: [] },
        headers: api_auth_headers
    end

    before { post_request }

    it { expect(response.status).to eq 400 }
  end
end

如您所见,我在 subject 块内的参数中使用了一个空数组。

控制器内部的值

在我的控制器中,我正在获取数据

params.require(:vendor_district_ids)

值如下

<ActionController::Parameters {"vendor_district_ids"=>[""], "controller"=>"api/my_controller", "action"=>"create"} permitted: false>

vendor_district_ids 的值是一个空字符串数组。当我用postman 发帖时,我没有相同的价值。

邮递员的价值

如果我发帖

{ "vendor_district_ids": [] }

控制器将收到

<ActionController::Parameters {"vendor_district_ids"=>[], "controller"=>"api/my_controller", "action"=>"create"} permitted: false>

这里的数组是空的。

问题

我在请求规范中做错了什么还是来自RSpec 的错误?

【问题讨论】:

  • 邮递员标头和测试中的标头有区别吗?特别找Content-Type
  • 只是一个想法,因为我刚刚遇到了类似的问题。如果你这样做会发生什么params: { "vendor_district_ids" =&gt; [] }
  • 看看我的回答,我想我已经总结出为什么我们会收到 Postman 和 RSPEC 之间的这种不一致的原因,以及避免修改控制器以解决空数组的解决方案。

标签: ruby-on-rails ruby rspec http-post rspec-rails


【解决方案1】:

找到答案了!

问题

问题是在 Rack 的 query_parser 中发现的,而不是在上一个答案所示的 rack-test 中。

"paramName[]="{"paramName":[""]} 的实际翻译发生在 Rack 的 query_parser 中。

问题的一个例子:

post '/posts', { ids: [] }
{"ids"=>[""]} # By default, Rack::Test will use HTTP form encoding, as per docs: https://github.com/rack/rack-test/blob/master/README.md#examples

解决方案

通过使用 'require 'json' 将 JSON gem 请求到您的应用程序中并将您的参数哈希附加到 .to_json 来将您的参数转换为 JSON。

并在您的 RSPEC 请求中指定此请求的内容类型为 JSON。

通过修改上例的例子:

post '/posts', { ids: [] }.to_json, { "CONTENT_TYPE" => "application/json" }
{"ids"=>[]} # explicitly sending JSON will work nicely

【讨论】:

  • 感谢您为我节省了数小时的拉头发时间。
【解决方案2】:

这实际上是由rack-test &gt;= 0.7.0 [1]引起的。

它将空数组转换为param[]=,然后解码为['']

如果您尝试运行相同的代码,例如rack-test 0.6.3 你会看到 vendor_district_ids 根本没有添加到查询中:

# rack-test 0.6.3
Rack::Test::Utils.build_nested_query('a' => [])
# => ""

# rack-test >= 0.7.0
Rack::Test::Utils.build_nested_query('a' => [])
# => "a[]="

Rack::Utils.parse_nested_query('a[]=')
# => {"a"=>[""]}

[1]https://github.com/rack-test/rack-test/commit/ece681de8ffee9d0caff30e9b93f882cc58f14cb

【讨论】:

    【解决方案3】:

    对于每个想知道的人 - 有一个快捷的解决方案:

    post '/posts', params: { ids: [] }, as: :json
    

    【讨论】:

      猜你喜欢
      • 2017-04-14
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多