Tengo el siguiente código en mi controlador:
format.json { render :json => {
:flashcard => @flashcard,
:lesson => @lesson,
:success => true
}
En mi prueba de controlador RSpec, quiero verificar que un determinado escenario reciba una respuesta json exitosa, así que obtuve la siguiente línea:
controller.should_receive(:render).with(hash_including(:success => true))
Aunque cuando ejecuto mis pruebas me sale el siguiente error:
Failure/Error: controller.should_receive(:render).with(hash_including(:success => false))
(#<AnnoController:0x00000002de0560>).render(hash_including(:success=>false))
expected: 1 time
received: 0 times
¿Estoy verificando la respuesta incorrectamente?
ruby-on-rails
json
rspec
Efervescencia
fuente
fuente
post :create
con un hash de parámetros válido.post :create, :format => :json
{"a":"1","b":"2"}
y{"b":"2","a":"1"}
no son cadenas iguales que anotan objetos iguales. No debes comparar cadenas sino objetos, hazlo en suJSON.parse('{"a":"1","b":"2"}').should == {"a" => "1", "b" => "2"}
lugar.Puede analizar el cuerpo de respuesta de esta manera:
Luego puede hacer sus afirmaciones contra ese contenido analizado.
fuente
b = JSON.parse(response.body, symoblize_names: true)
para poder acceder a ellos usando símbolos como este:b[:foo]
Partiendo de la respuesta de Kevin Trowbridge
fuente
Mime::JSON
lugar de'application/json'
?Mime::JSON.to_s
También está la gema json_spec , que vale la pena ver
https://github.com/collectiveidea/json_spec
fuente
Simple y fácil de hacer esto.
fuente
También puede definir una función auxiliar dentro
spec/support/
y úselo
json_body
cuando necesite acceder a la respuesta JSON.Por ejemplo, dentro de la especificación de su solicitud, puede usarla directamente
fuente
Otro enfoque para probar solo una respuesta JSON (no es que el contenido contenga un valor esperado), es analizar la respuesta usando ActiveSupport:
Si la respuesta no es JSON analizable, se lanzará una excepción y la prueba fallará.
fuente
¿Podrías mirar dentro del
'Content-Type'
encabezado para ver si es correcto?fuente
render :json => object
creo que Rails devuelve un encabezado Content-Type de 'application / json'.response.header['Content-Type'].should match /json/
Al usar Rails 5 (actualmente todavía en beta), hay un nuevo método,
parsed_body
en la respuesta de prueba, que devolverá la respuesta analizada en la que se codificó la última solicitud.El commit en GitHub: https://github.com/rails/rails/commit/eee3534b
fuente
#parsed_body
. Todavía no está documentado, pero al menos el formato JSON funciona. Tenga en cuenta que las teclas siguen siendo cadenas (en lugar de símbolos), por lo que uno puede encontrarlas#deep_symbolize_keys
o#with_indifferent_access
útiles (me gusta la última).Si desea aprovechar el hash diff que proporciona Rspec, es mejor analizar el cuerpo y compararlo con un hash. La forma más simple que he encontrado:
fuente
Solución de comparación JSON
Produce un Diff limpio pero potencialmente grande:
Ejemplo de salida de consola de datos reales:
(Gracias a comentar por @floatingrock)
Solución de comparación de cadenas
Si desea una solución revestida de hierro, debe evitar el uso de analizadores que podrían introducir una falsa igualdad positiva; compare el cuerpo de respuesta con una cadena. p.ej:
Pero esta segunda solución es menos amigable visualmente ya que utiliza JSON serializado que incluiría muchas comillas escapadas.
Solución de igualación personalizada
Tiendo a escribirme un matizador personalizado que hace un trabajo mucho mejor al señalar exactamente en qué ranura recursiva difieren las rutas JSON. Agregue lo siguiente a sus macros rspec:
Ejemplo de uso 1:
Ejemplo de uso 2:
Salida de ejemplo:
Otro resultado de ejemplo para demostrar una falta de coincidencia profunda en una matriz anidada:
Como puede ver, la salida le dice EXACTAMENTE dónde arreglar su JSON esperado.
fuente
Encontré un contacto con el cliente aquí: https://raw.github.com/gist/917903/92d7101f643e07896659f84609c117c4c279dfad/have_content_type.rb
Póngalo en spec / support / matchers / have_content_type.rb y asegúrese de cargar cosas del soporte con algo como esto en su spec / spec_helper.rb
Aquí está el código en sí mismo, en caso de que desaparezca del enlace dado.
fuente
Muchas de las respuestas anteriores están un poco desactualizadas, por lo que este es un resumen rápido de una versión más reciente de RSpec (3.8+). Esta solución no genera advertencias de rubocop-rspec y está en línea con las mejores prácticas de rspec :
Una respuesta JSON exitosa se identifica por dos cosas:
application/json
Suponiendo que el objeto de respuesta es el sujeto anónimo de la prueba, ambas condiciones anteriores se pueden validar utilizando los comparadores integrados de Rspec:
Si está preparado para nombrar a su sujeto, las pruebas anteriores se pueden simplificar aún más:
fuente