web-dev-qa-db-fra.com

Rspec teste redirect_to: retour

Comment testez-vous redirect_to :back dans rspec?

Je reçois

ActionController::RedirectBackError:
Non HTTP_REFERER a été défini dans la demande de cette action, donc redirect_to :back n'a pas pu être appelé avec succès. S'il s'agit d'un test, assurez-vous de spécifier request.env["HTTP_REFERER"].

Comment puis-je configurer le HTTP_REFERER dans mon test?

62
Cyrus

À l'aide de RSpec, vous pouvez définir le référent dans un bloc before. Lorsque j'ai essayé de définir le référent directement dans le test, cela ne semblait pas fonctionner, peu importe où je l'ai mis, mais le bloc avant fait l'affaire.

describe BackController < ApplicationController do
  before(:each) do
    request.env["HTTP_REFERER"] = "where_i_came_from"
  end

  describe "GET /goback" do
    it "redirects back to the referring page" do
      get 'goback'
      response.should redirect_to "where_i_came_from"
    end
  end
end
112
joshuarh

Du Guide Rails lors de la demande de la demande avec le nouveau style de demande:

describe BackController < ApplicationController do
  describe "GET /goback" do
    it "redirects back to the referring page" do
      get :show, 
        params: { id: 12 },
        headers: { "HTTP_REFERER" => "http://example.com/home" }
      expect(response).to redirect_to("http://example.com/home")
    end
  end
end
3
ivanxuu

Si quelqu'un tombe dessus et utilise des spécifications request, vous devrez définir explicitement les en-têtes sur la demande que vous faites. Le format de la demande de test dépend de la version de RSpec que vous utilisez et si vous pouvez utiliser des arguments de mots clés au lieu d'arguments positionnels.

let(:headers){ { "HTTP_REFERER" => "/widgets" } }

it "redirects back to widgets" do 
  post "/widgets", params: {}, headers: headers # keyword (better)
  post "/widgets", {}, headers                  # positional

  expect(response).to redirect_to(widgets_path)
end

https://relishapp.com/rspec/rspec-Rails/docs/request-specs/request-spec

3
sp89

À mon humble avis, la réponse acceptée est un peu hacky. Une meilleure alternative serait de définir le HTTP_REFERER vers une URL réelle dans votre application, puis attendez-vous à être redirigé:

describe BackController, type: :controller do
  before(:each) do
    request.env['HTTP_REFERER'] = root_url
  end

  it 'redirects back' do
    get :whatever
    response.should redirect_to :back
  end
end
  • La redirection vers une constante de chaîne aléatoire donne l'impression que cela fonctionne par accident
  • Vous profitez des fonctionnalités intégrées de rspec pour exprimer exactement ce que vous vouliez
  • Vous n'introduisez pas et ne répétez pas les valeurs de chaîne magique

Pour les versions plus récentes de rspec, vous pouvez utiliser les attentes à la place:

expect(response).to redirect_to :back
1
ndnenkov

En ce qui concerne les tests: retour des liens dans les tests d'intégration, je visite d'abord une page morte, qui, je pense, ne sera probablement jamais utilisée comme lien, puis la page que je teste. Donc mon code ressemble à ceci

   before(:each) do
       visit deadend_path
       visit testpage_path
    end
    it "testpage Page should have a Back button going :back" do
      response.should have_selector("a",:href => deadend_path,
                                        :content => "Back")
    end

Cependant cela a le défaut que si le lien est vraiment vers le deadend_path, alors le test passera incorrectement.

1
Obromios