2010-10-27 23 views
19

Estoy intentando construir una prueba rspec que envíe JSON (o XML) a través de POST. Sin embargo, me parece que no puede conseguir realmente que funcione:Especificación del tipo de contenido en rspec

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

y esto

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

alguna idea? ¡GRACIAS!

+0

Por lo general, usted publique en una acción en un controlador. ¿Por qué estás publicando en un archivo? –

+0

Este es un modelo RESTful – skeevis

Respuesta

17

Hay una manera de hacer esto se describe en this thread - es un truco, pero parece que funciona:

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

Esto funciona con Rspec 2 y rieles 3. (y fue extremadamente difícil de encontrar) En realidad, no tuve que usar .to_json para que se comporte correctamente.De lo contrario, todo lo demás funcionaba bien. – BeepDog

+0

Gracias. Me costó mucho buscar la solución a mis pruebas fallidas antes de leer su respuesta. – Salil

+0

Sí, esto todavía funciona con RSpec 3 ('rspec (2.11.0)'). Hurra. – sorens

5

En primer lugar, usted no quiere poner a prueba el incorporado en la conversión de JSON a hash. Lo mismo se aplica a xml.

Prueba el controlador con los datos como hash, sin molestar si es json, xml o de un formulario html.

Pero si le gustaría hacer eso como un ejercicio, se trata de un script ruby ​​independiente para hacer juego con el :)

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 

para cambiar a XML, utilice content_type="text/xml" y

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

Una prueba un poco más elegante es utilizar el encabezado helper:

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

Ahora esto hace exactamente th Lo mismo que establecer @env; es un poco más bonito.

+0

¿Dónde se define este método? Obtengo un NoMethodError cuando intento llamarlo. –

+0

@PaulBrannan Es [en rack/prueba] (https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L134) –

14

En Rails 3, puede omitir el encabezado y @request.env cosas y sólo tiene que añadir un parámetro format a su llamada posterior, por ejemplo .:

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

¿El uso de 'formato:: json' establecer' request.accept' y 'request.content_type' a' "application/json" '? – Dennis

+0

[Este problema en rspec-rails] (https://github.com/rspec/rspec-rails/issues/710) implica que 'format:: json' es lo mismo que' request.accept = "application/json" '. – Dennis

+1

Parece que en las versiones posteriores de rails/rspec, 'format:: json' ha cambiado a' as:: json' – dkniffin

9

Una gran cantidad de frustración y variaciones y eso es lo que funcionó para mí. rieles 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

¡Gracias! Descubrí el que funcionaba para mí gracias a su respuesta: '@ request.env [" CONTENT_TYPE "] =" application/json "'. – rchampourlier

+0

'HTTP_ACCEPT' también es necesario si desea que su controlador devuelva JSON ... – rchampourlier

0

La mejor manera que he encontrado para probar estas cosas es con las pruebas de petición. Las pruebas de solicitud pasan por las etapas completas de análisis y enrutamiento de Rails. Así que puedo escribir una prueba como esta:

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 
0

Creo que se puede especificar las cabeceras con headers param:

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

Siguiendo la documentación Rspec de how provide JSON data.

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

o pasar en la solicitud de

"CONTENT_TYPE" => "application/json"

Cuestiones relacionadas