【问题标题】:Specifying Content Type in rspec在 rspec 中指定内容类型
【发布时间】:2017-10-31 19:32:39
【问题描述】:

我正在尝试构建一个通过 POST 发送 JSON(或 XML)的 rspec 测试。但是,我似乎无法真正让它工作:

    json = {.... data ....}.to_json
    post '/model1.json',json,{'CONTENT_TYPE'=>'application/json'}

还有这个

    json = {.... data ....}.to_json
    post '/model1.json',json,{'Content-Type'=>'application/json'}

有什么想法吗?谢谢!

【问题讨论】:

  • 通常你发布到控制器中的一个动作。为什么要发布到文件中?

标签: ruby rspec sinatra rack


【解决方案1】:

this thread 中描述了一种方法来做到这一点——这是一个 hack,但它似乎有效:

@request.env["HTTP_ACCEPT"] = "application/json"
json = { ... data ... }.to_json
post :create, :some_param => json

【讨论】:

  • 这适用于 Rspec 2 和 rails 3。(而且很难找到)实际上,我必须不使用 .to_json 来让它正常运行。否则,其他一切正常。
  • 谢谢。在阅读您的答案之前,我很难为我的失败测试寻找解决方案。
  • 我还发现request.accept = 'application/json' 也可以。
【解决方案2】:

在 Rails 3 中,您可以跳过标题和 @request.env 内容,只需在 post 调用中添加 format 参数,例如:

post :create, format: :json, param: 'Value of Param'

【讨论】:

  • 是否使用format: :jsonrequest.acceptrequest.content_type 设置为"application/json"
  • This issue on rspec-rails 表示format: :jsonrequest.accept = "application/json" 相同。
  • 看起来在更高版本的 rails/rspec 中,format: :json 已更改为 as: :json
【解决方案3】:

很多挫折和变化,这对我有用。 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"

【讨论】:

  • 谢谢!感谢您的回答,我找到了适合我的人:@request.env["CONTENT_TYPE"] = "application/json"
【解决方案4】:

首先,你不想测试json到hash的内置转换。同样适用于 xml。

您使用数据作为哈希值来测试控制器,而不管它是 json、xml 还是来自 html 表单。

但是,如果您想将其作为练习,这是一个独立的 ruby​​ 脚本,可以玩 :)

require 'json'
url = URI.parse('http://localhost:3030/mymodels.json')
request = Net::HTTP::Post.new(url.path)
request.content_type="application/json"
request.basic_auth('username', 'password')  #if used, else comment out

hash = {:mymodel => {:name => "Test Name 1", :description => "some data for testing description"}}
request.body = hash.to_json
response = Net::HTTP.start(url.host, url.port) {|http| http.request(request)}
puts response

要切换到 xml,请使用 content_type="text/xml"

request.body = "<?xml version='1.0' encoding='UTF-8'?><somedata><name>Test Name 1</name><description>Some data for testing</description></somedata>"

【讨论】:

    【解决方案5】:

    一个更优雅的测试是使用 header helper:

    header "HTTP_ACCEPT", "application/json"
    json = {.... data ....}.to_json
    post '/model1.json', json
    

    现在这与设置@env 完全相同;就是漂亮了一点。

    【讨论】:

    • 这个方法是在哪里定义的?当我尝试调用它时,我得到一个 NoMethodError。
    • @PaulBrannan 这是in rack/test
    【解决方案6】:

    我发现测试这些东西的最佳方法是使用请求测试。请求测试通过 Rails 的完整参数解析和路由阶段。所以我可以写一个这样的测试:

    request_params = {:id => 1, :some_attribute => "some value"}
    headers = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}
    put "/url/path", request_params.to_json, headers
    expect(response).to be_success
    

    【讨论】:

      【解决方案7】:

      我认为您可以使用headers 参数指定标题:

      post '/model1.json', headers: {'Content-type': 'application/json'}
      

      遵循how provide JSON data 的 Rspec 文档。

      【讨论】:

        【解决方案8】:
        @request.env["CONTENT_TYPE"] = "application/json"
        

        或传递请求

        "CONTENT_TYPE" =&gt; "application/json"

        【讨论】:

          猜你喜欢
          • 2014-07-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-15
          • 1970-01-01
          • 1970-01-01
          • 2019-02-19
          • 1970-01-01
          • 2020-05-10
          相关资源
          最近更新 更多