Rspec testing redirect_to :back
Asked Answered
V

6

65

How do you test redirect_to :back in rspec?

I get

ActionController::RedirectBackError:
No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].

How do I go about setting the HTTP_REFERER in my test?

Value answered 18/5, 2011 at 6:0 Comment(2)
It might be useful to see the test source itself. This might be symptomatic of another issue...Decoupage
I was able to alleviate this error by calling 'visit root_path' first. But I think I can only do that in an integration test. Is that right?Value
Q
119

Using RSpec, you can set the referer in a before block. When I tried to set the referer directly in the test, it didn't seem to work no matter where I put it, but the before block does the trick.

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
Quatre answered 18/7, 2011 at 7:28 Comment(3)
I found it was a good idea to use: request.env["HTTP_REFERER"] = "where_i_came_from" unless request.nil? or request.env.nil?Precocity
yeah. for me it is always nil and it is just not working. Looks like a huge bug to me.Butterfly
It may have been updated to fix this issue since this answer was created, but I'm able to successfully set request.env["HTTP_REFERER"] in my test without using a before block.Giza
K
5

If someone stumbles upon this and they're using request specs, you'll need to explicitly set the headers on the request you're making. The format of the test request depends on which version of RSpec you're using and if you can use keyword arguments instead of positional arguments.

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

Kassa answered 20/7, 2017 at 6:32 Comment(0)
D
4

From the rails guide when requesting the request with the new request style:

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
Dorree answered 21/10, 2016 at 18:19 Comment(0)
S
3

IMHO the accepted answer is a bit hacky. A better alternative would be to set the HTTP_REFERER to an actual url in your application and then expect to be redirected back:

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
  • Redirecting to a random string constant feels as if it works by accident
  • You take advantage of rspec's built in functionality to express exactly what you wanted
  • You don't introduce and repeat magic string values

For newer versions of rspec, you can use expectations instead:

expect(response).to redirect_to :back
Stupefacient answered 18/4, 2016 at 14:51 Comment(0)
T
1

In regard to testing :back links in integration tests, I first visit a deadend page, that I think is not likely to be ever used as a link, and then the page I am testing. So my code looks like this

   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

However this does have the flaw that if the link is really to the deadend_path, then the test will incorrectly pass.

Tazza answered 23/5, 2012 at 23:42 Comment(0)
D
-2
request.env['HTTP_REFERER'] = '/your_referring_url'
Dall answered 7/6, 2011 at 18:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.