为RSpec和Rails-API设置Content-Type标头

时间:2012-12-18 20:20:23

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

我正在使用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为nil),我发现的其他任何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 hash的内容(注意添加项目键):

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

是否可以仅使用RSpec设置内容类型标题?或者我是否必须使用机架/测试来实现此功能?

7 个答案:

答案 0 :(得分:21)

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

答案 1 :(得分:6)

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

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

wrap_parameters Project, format: :json

答案 2 :(得分:5)

仅使用新的Rails v5.0.x API设置我发现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",您还可以include块中的Describe 'something' do块手动@echo off color f0 title Nim In Batch ::: Main Menu :main set /a coins=12 set /a time=0 cls echo Nim In Batch! echo. choice /n /c pr /m "Play Or See Rules?" if %errorlevel%==1 ( goto play ) if %errorlevel%==2 ( goto rules ) ::: Rules :rules cls echo Objective: Be the one to claim the last coin echo. echo Rules: echo -You Play First echo -You Must Remove 1,2 Or 3 Coins Each Turn echo -Turns Switch Once Coins Are Removed echo -Coins Must Be Removed In Order echo. echo Ready? pause>nul goto main ::: Game :play cls echo (%coins%) Coins echo. choice /n /c 123 /m "How Many Coins Do You Wish To Remove?" if %errorlevel%==1 ( set /a Coins=%coins%-1 ) if %errorlevel%==2 ( set /a Coins=%coins%-2 ) if %errorlevel%==3 ( set /a Coins=%coins%-3 ) cls echo (%coins%) Coins echo. echo Computer Is Thinking ping 1.1.1.1 -n 1 -w 3250 >NUL if %errorlevel%==1 ( set /a Coins=%coins%-3 ) if %errorlevel%==2 ( set /a Coins=%coins%-2 ) if %errorlevel%==3 ( set /a Coins=%coins%-1 ) if %coin%==0 ( goto end ) else ( goto play ) :end cls echo Computer Wins! echo He Collected The Final Coin! echo. pause goto main

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

没有5次黑客入侵:

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

这样可以正确设置content_type。在控制器中,params将同时包含参数和主体。

答案 6 :(得分:0)

导轨 5

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

在那个请求之后

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

并从请求路由中删除 .to_json