开发者

Rspec testing redirect_to :back

开发者 https://www.devze.com 2023-03-07 02:51 出处:网络
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.

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?


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


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


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


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


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.


request.env['HTTP_REFERER'] = '/your_referring_url'
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号