【问题标题】:Setting Content-Type header for RSpec and Rails-API为 RSpec 和 Rails-API 设置 Content-Type 标头
【发布时间】:2012-12-18 20:20:22
【问题描述】:

我正在使用 rails-api gem 构建 Web 服务,并希望使用 RSpec 测试我的 API。无论使用哪种 HTTP 方法,我发出的每个请求都将 CONTENT_TYPE 标头设置为“application/x-www-form-urlencoded”。在我尝试在我的控制器中使用 wrap_parameters 并且它对 params 哈希没有任何影响之前,这并不是一个真正的问题:

class ApplicationController < ActionController::API
  include ActionController::ParamsWrapper
end

class ProjectsController < ApplicationController
  wrap_parameters :project, include: [:name]
  # ...
end

This hack 不再有效(@request 为零),我发现的其他 Stack Overflow 帖子也没有。

如果我在我的 RSpec 测试中提出以下请求:

put "/projects/1.json", {name: 'Updated Project 1'}

并在我的控制器中放置一个调试器:

(rdb:1) p params
    { "name"=>"Updated Project 1",
  "action"=>"update",
  "controller"=>"projects",
  "id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507",
  "format"=>"json"
}

(rdb:1) p request.content_type
"application/x-www-form-urlencoded"

我希望在 params 哈希中看到类似的内容(注意添加了项目密钥):

{ "name"=>"Updated Project 1",
  "action"=>"update",
  "controller"=>"projects",
  "id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507",
  "format"=>"json",
  "project" => {"name" => "Updated Project 1"}
}

是否可以仅使用 RSpec 设置内容类型标头?还是我必须使用 rack/test 来实现这个功能?

【问题讨论】:

  • wrap_parameters is still busted 有可能与 rails-api 项目有关,这与设置内容类型无关。
  • 通过将 :url_encoded_form 格式添加到方法调用中确认 wrap_parameters 起作用:wrap_parameters format: [:url_encoded_form, :json]
  • 您可以使用request.env['HTTP_CONTENT_TYPE'] = 'application/json' 或您需要的任何其他内容在控制器中设置rspec 请求环境的元素。

标签: ruby-on-rails rspec ruby-on-rails-3.2 rails-api


【解决方案1】:

很多挫折和变化,这对我有用。 Rails 3.2.12 Rspec 2.10

 @request.env["HTTP_ACCEPT"] = "application/json"
 @request.env["CONTENT_TYPE"] = "application/json"
 put :update, :id => 1, "email" => "bing@test.com"

wrap_parameters 似乎是这样声明的

wrap_parameters User, format: :json

用于User 模型

【讨论】:

  • 这真的让我大吃一惊。设置put :update, :id =&gt; 1, :format =&gt; :json不起作用。你必须像 VelLes 一样进入。
【解决方案2】:

如果有人在寻找更新的版本,这对我 Rails 4.0.3Rspec 2.14.1 有用。

put '/projects/1.json', {name: 'Updated Project 1'}, {
  'HTTP_ACCEPT' => 'application/json',
  'CONTENT_TYPE' => 'application/json'
}

wrap_parameters Project, format: :json

【讨论】:

  • 我删除了参数的 .to_json 并且它起作用了:put '/projects/1.json', {name: 'Updated Project 1'}, { 'HTTP_ACCEPT' =&gt; 'application/json', 'CONTENT_TYPE' =&gt; 'application/json' }
【解决方案3】:

使用新的 Rails v5.0.x API only 设置我发现 Rails 将所有内容默认为 "application/x-www-form-urlencoded" 的问题仍然存在于使用 RSpec-Rails 请求进行测试的问题

这是我解决问题的方法:

./spec/support/json_requests.rb创建支持文件

将其编辑为类似这样以覆盖所有仅 API JSON 请求的行为:

module JsonRequests
  def get(*args)
    super(*json_args(*args))
  end

  def post(*args)
    super(*json_args(*args))
  end

  def update(*args)
    super(*json_args(*args))
  end

  def patch(*args)
    super(*json_args(*args))
  end

  def put(*args)
    super(*json_args(*args))
  end

  def delete(*args)
    super(*json_args(*args))
  end

  def json_args(path, params = {}, headers = {})
    [path, params.to_json, headers.merge('CONTENT_TYPE' => 'application/json')]
  end
end

RSpec.configure do |config|
  config.include JsonRequests, type: :request
end

请记住,这将覆盖./spec/requests 中的所有规范,因此如果您需要使用"application/x-www-form-urlencoded",您也可以根据需要在Describe 'something' do 块中手动使用include 这个模块。

【讨论】:

  • 使用 ruby​​ 2.5.0、rails 5.1.5 和 rspec 3.7.1,我不得不将上面的 json_args 方法更改为:def json_args(path, params = {})[path, **params.merge(as: :json)]end 参见此处:@ 987654321@
【解决方案4】:

Rails 5 没有破解:

put(:update,
    params: {project_id: 1},
    body: {name: 'Updated Project 1'}.to_json,
    as: :json)

这会正确设置content_type。在控制器中params 将同时保存参数和正文。

【讨论】:

    【解决方案5】:

    到了 2021 年,Rails 6.1 和我不得不使用 as: :json 来修复参数中哈希数组的这种奇怪的修改。

    put(:update, params: the_params_hash, as: :json)
    

    【讨论】:

    • 你拯救了我的一天!谢谢
    【解决方案6】:

    如果您使用的是 Rails 4(和 rspec ~3.7)并且不想使用内联语法:

    request.headers["CONTENT_TYPE"] = "application/json"
    

    【讨论】:

      【解决方案7】:

      轨道 5

      headers = { 'CONTENT_TYPE' => 'application/json' }
      params = { user_type: 'tester' } 
      

      在那个请求之后

      post '/api/v1/users/test', params.to_json, headers
      

      并从请求路由中删除.to_json

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-10
        • 2015-05-05
        • 2013-07-22
        • 2012-05-27
        • 2011-07-21
        相关资源
        最近更新 更多