【问题标题】:Rails/Rspec JSON integers being converted to strings when testing post call测试后调用时将 Rails/Rspec JSON 整数转换为字符串
【发布时间】:2016-07-19 21:48:41
【问题描述】:

我正在测试对我们 API 的 JSON 请求,它将以 JSON 响应。 似乎 JSON 中的所有整数都被转换为字符串,因为我们将它们发布到控制器考虑操作。

控制器

  def consider
    binding.pry # binding no# 2 used to check the params after post from test.
    if ParametersValidator.is_valid?(params)
      application_handler = ApplicationHandler.new(request_interactor)
      render json: application_handler.result
    else
      render json: ParametersValidator.failed_params(params).to_json
    end
  end

ParamaterValidator 验证传入数据的结构和类型。

测试

render_views
let(:json) { JSON.parse(response.body) }
..
..

it 'returns the result in the correct format for the AUTOMATIC APPROVE decision' do
  automatic_approve_params = relative_json_file(relative_file('automatic_approve_params'))
  expected_approve_params = {
    "status" => "accepted",
    "automated" => true,
    "rate" => 6,
    "amount" => 30000,
    "term" => 10,
    "pre_approved_amount" => 2500,
    "comments" => ""
  }
  @request.headers['HTTP_X_AUTH_SIG'] = Rails.application.secrets['authorization']['token']
  request.env["HTTP_ACCEPT"] = 'application/json'

  binding.pry  # binding no# 1 to inspect the params before post

  post :consider, automatic_approve_params, format: :json
  expect(json).to eq(expected_approve_params)
end

绑定编号#1

{
 "student_id"=>1,
 "age"=>22,
 "name"=>"John",
 "age_range"=>"22-25",
 "criminal_record"=>false,
 "declared_bankrupt"=>false,
 "declared_insolvent"=>false,
 "declared_sequestrated"=>false,
 "defaulted_on_loan"=>false,
 "post_study_salary"=>100000000,
 "first_nationality"=>"PL",
 "second_nationality"=>"",
 "citizenship"=>"PL",
}

绑定编号#2

{
 "student_id"=>"1",
 "age"=>"22",
 "name"=>"John",
 "age_range"=>"22-25",
 "criminal_record"=>false,
 "declared_bankrupt"=>false,
 "declared_insolvent"=>false,
 "declared_sequestrated"=>false,
 "defaulted_on_loan"=>false,
 "post_study_salary"=>"100000000",
 "first_nationality"=>"PL",
 "second_nationality"=>"",
 "citizenship"=>"PL",
}

测试日志显示请求是

Processing by Api::V1::CreditApplicationsController#consider as JSON

在发布操作之前检查请求,您会看到参数很好,然后在控制器中,在我运行任何东西之前检查参数,它们都是字符串。

使用 postman 测试带有 JSON 的 API 可以按预期工作,但似乎 rspec 在发布到考虑操作时会将所有参数转换为字符串。我已经阅读了几十篇声称通过在帖子操作中添加format: :json 来解决此问题的帖子,但是我没有这样的运气。

我显然做错了什么,但我已经尝试了我所知道的几乎所有东西。

【问题讨论】:

  • 不是所有的http参数和变量总是作为字符串发送吗?你如何与邮递员核实他们是以整数的形式进来的?
  • 发现它被包裹在一个字符串中,然后在另一端解析。我将上面的内容更改为集成测试,并做了一些 JSON 魔术及其工作。
  • @TheLegend 也有同样的问题,你能描述一下你的解决方案吗?干杯。
  • @mecampbellsoup HannesBenson 的回答是解决方案。奇怪的真正原因是隐藏在 Rails 中的魔法。它会将其转换为字符串,因为ActionController::Base 会获取它对其进行清理的参数以确保通常是安全的。
  • @TheLegend 是的,您在 OP 中没有提到的一件事是您的规格是 RSpec 控制器规格(对吗?),而不是功能/请求规格。我相信这会改变参数转换行为。

标签: ruby-on-rails ruby json rspec


【解决方案1】:

复制您遇到的问题后,我设法使用以下方法在控制器规范中解决了它:

post :consider, automatic_approve_params.merge(format: :json)

在我的本地测试中,我删除了 request.env["HTTP_ACCEPT"] = 'application/json' 它仍然按您的预期工作。希望对您有所帮助。

【讨论】:

  • 在 Rails 5 中,使用 as: :json 而不是 format: :json,例如post :consider, params: automatic_approve_params, as: :json
  • @RichKuzsma 请添加您的评论作为单独的答案!
【解决方案2】:

在 Rails 5 中,使用 as: :json 而不是 format: :json,例如post :consider, params: automatic_approve_params, as: :json

【讨论】:

    【解决方案3】:

    我们可以试试这个

    post 'orders.json', JSON.dump(order: {boolean: true, integer: 123}), "CONTENT_TYPE" => "application/json"
    

    【讨论】:

    • 这似乎将参数嵌套在第二组 {} 中,其中包含反斜杠和引号。如何将我们写的内容(“mykey : 5)”发送到最低级别的 params 散列中,而不在字符串中添加任何格式等?
    猜你喜欢
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多