RSpec test de redirection d'URL avec paramètres

disons que j'ai un FoosController avec un redirect_to_baz méthode.

class FoosController < ApplicationController

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

end

je teste ça avec 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

Cela fonctionne. Cependant, si quelqu'un échange les paramètres de la chaîne de requête (par exemple http://example.com/?bar=2&baz=3&foo=1), le test échoue.

Quelle est la bonne façon de tester ceci?

j'aimerais faire quelque chose comme:

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

j'ai regardé l' documentation et j'ai essayé de chercher response.parameters, mais je n'ai rien trouvé pareil. Même Hash#to_query ne semble pas résoudre ce problème.

Toute aide serait grandement appréciée.

22
demandé sur Simone 2014-05-29 02:31:38

2 réponses

documentation, le chemin de redirection attendu peut correspondre à un regex:

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

pour vérifier la chaîne de requête de l'emplacement de la redirection semble un peu plus alambiquée. Vous avez accès à l'emplacement de la réponse, donc vous devriez être en mesure de le faire:

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

Vous devriez être en mesure d'extraire la chaîne de requête params comme ceci:

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

et à partir de là, il devrait être simple de vérifier que les paramètres de redirection sont correct:

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

si vous devez faire ce genre de logique plus d'une fois cependant, il serait certainement pratique de tout envelopper dans un RSpec matcher personnalisé.

23
répondu hjing 2014-05-29 00:05:05

Êtes-vous capable d'utiliser vos aides de route plutôt qu'une simple chaîne? Si c'est le cas, vous pouvez simplement passer des paramètres de hachage à un Helper route et ils seront convertis en paramètres de chaîne de requête:

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'))

Est-ce que cela aide, ou Êtes-vous limité à utiliser des chaînes plutôt que des helpers de route?

une autre pensée est que vous pourriez juste affirmer directement sur les valeurs dans le hachage params plutôt que l'url + chaîne de requête, puisque la chaîne de requête params sera sérialisé dans les paramètres hachage...

4
répondu Cade 2014-05-28 23:08:51