rails example databasecleaner ruby-on-rails ruby rspec parameters response

ruby-on-rails - example - rails selenium



Pruebas RSpec redireccionan a URL con parĂ¡metros GET (3)

¿Puedes usar tus ayudantes de ruta en lugar de una cadena simple? Si es así, simplemente puede pasar parámetros de hash a un ayudante de ruta y se convertirán a parámetros de cadena de consulta:

root_url foo: ''bar'', baz: ''quux'' => "http://www.your-root.com/?baz=quux&foo=bar" expect(response).to redirect_to(root_url(foo: ''bar'', baz: ''quux''))

¿Ayuda eso, o está restringido a usar cadenas en lugar de ayudantes de ruta?

Otra idea es que simplemente puede hacer valer directamente los valores en el hash de params en lugar de la cadena url + query, ya que los params de cadena de consulta se serializarán en el hash de params ...

Digamos que tengo un FoosController con un método redirect_to_baz .

class FoosController < ApplicationController def redirect_to_baz redirect_to ''http://example.com/?foo=1&bar=2&baz=3'' end end

Estoy probando esto con spec/controllers/foos_controller_spec.rb :

require ''spec_helper'' describe FoosController, :type => :controller do describe "GET redirect_to_baz" do it "redirects to example.com with params" do get :redirect_to_baz expect(response).to redirect_to "http://example.com/?foo=1&bar=2&baz=3" end end end

Funciona. Sin embargo, si alguien intercambia los parámetros de la cadena de consulta (por ejemplo, http://example.com/?bar=2&baz=3&foo=1 ), la prueba falla.

¿Cuál es la forma correcta de probar esto?

Me gustaría hacer algo como:

expect(response).to redirect_to("http://example.com/", params: { foo: 1, bar: 2, baz: 3 })

Miré la documentation e intenté buscar parámetros de response.parameters , pero no encontré nada de eso. Incluso Hash#to_query no parece resolver este problema.

Cualquier ayuda sería muy apreciada.


De la documentation , la ruta de redirección esperada puede coincidir con una expresión regular:

expect(response).to redirect_to %r(/Ahttp://example.com)

Para verificar la cadena de consulta de la ubicación de redireccionamiento parece un poco más complicado. Tienes acceso a la ubicación de la respuesta, por lo que deberías poder hacer esto:

response.location # => http://example.com?foo=1&bar=2&baz=3

Deberías poder extraer los parámetros de la cadena de consulta de esta manera:

redirect_params = Rack::Utils.parse_query(URI.parse(response.location).query) # => {"foo"=>"1", "bar"=>"2", "baz"=>"3"}

Y a partir de eso, debería ser sencillo verificar que los parámetros de redireccionamiento son correctos:

expect(redirect_params).to eq("foo" => "1", "baz" => "3", "bar" => "2") # => true

Sin embargo, si tiene que hacer este tipo de lógica más de una vez, definitivamente sería conveniente envolverlo todo en un emparejador de rspec personalizado.


Necesitaba algo similar y terminé con esto:

Pudo escribir pruebas y no preocuparse por el orden de los parámetros de consulta.

expect(response.location).to be_a_similar_url_to("http://example.com/?beta=gamma&alpha=delta")

Coloque lo siguiente en ./spec/support/matchers/be_a_similar_url_to.rb

RSpec::Matchers.define :be_a_similar_url_to do |expected| match do |actual| expected_uri = URI.parse(expected) actual_uri = URI.parse(actual) expect(actual_uri.host).to eql(expected_uri.host) expect(actual_uri.port).to eql(expected_uri.port) expect(actual_uri.scheme).to eql(expected_uri.scheme) expect(Rack::Utils.parse_nested_query(actual_uri.query)).to eql(Rack::Utils.parse_nested_query(expected_uri.query)) expect(actual_uri.fragment).to eql(expected_uri.fragment) end # optional failure_message do |actual| "expected that #{actual} would be a similar URL to #{expected}" end # optional failure_message_when_negated do |actual| "expected that #{actual} would not be a similar URL to #{expected}" end end