在rspec中指定内容类型

问题描述:

我试图构建一个通过POST发送JSON(或XML)的rspec测试。不过,我似乎无法真正得到它的工作:在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'} 

什么想法?谢谢!

+0

通常你POST在控制器的动作。你为什么张贴到一个文件? – 2010-10-27 23:15:35

+0

这是一个RESTful模型 – skeevis 2010-10-28 01:28:57

有一种方法在this thread这说明做 - 这是一个黑客,但它似乎工作:

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

这适用于Rspec 2和rails 3.(并且极难找到) 实际上,我不得不使用.to_json来使它正常工作。否则,一切工作正常。 – BeepDog 2011-02-18 21:04:41

+0

谢谢。在阅读您的答案之前,我已经很难找到解决我的失败测试的解决方案。 – Salil 2012-06-05 08:35:48

+0

是的,这仍然适用于RSpec 3('rspec(2.11.0)')。好极了。 – sorens 2012-11-02 18:29:48

首先,你不想要测试的内置JSON的转换散列。同样适用于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>" 

一个稍微更优雅的测试是使用标头助手:

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

现在,这确实是th与设置@env相同的东西;它只是更漂亮一点。

+0

这个方法在哪里定义?当我尝试调用它时,我得到一个NoMethodError。 – 2012-11-29 20:35:16

+0

@PaulBrannan这是[在机架/测试](https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L134) – 2012-11-29 20:49:24

在Rails 3,您可以跳过头和@request.env的东西,只需添加一个format参数到您的文章通话,例如:

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

是否使用'format :: json' set' request.accept'和'request.content_type'到''application/json“'? – Dennis 2014-11-24 15:59:01

+0

[rspec-rails上的这个问题](https://github.com/rspec/rspec-rails/issues/710)意味着'format :: json'与request.accept =“application/json”相同'。 – Dennis 2014-11-24 16:10:45

+1

看起来在rails/rspec的后期版本中,'format :: json'变成'as :: json' – dkniffin 2016-12-05 18:55:17

太多的无奈和变化,这对我工作。 的Rails 3.2.12 Rspec的2.10

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

谢谢!我找到了一个为我工作的感谢您的答案:'@ request.env [“CONTENT_TYPE”] =“application/json”'。 – rchampourlier 2013-05-31 09:05:05

+0

如果您希望控制器返回JSON,则还需要HTTP_ACCEPT ... – rchampourlier 2013-05-31 09:31:58

,我发现来测试这些东西的最佳方式是与要求的测试。请求测试通过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 

我认为你可以用headers PARAM指定标题:

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

how provide JSON data的Rspec的文档。

@request.env["CONTENT_TYPE"] = "application/json" 

,或传入请求

"CONTENT_TYPE" => "application/json"