问题
How do you test redirect_to :back
in rspec?
I get
ActionController::RedirectBackError
:
NoHTTP_REFERER
was set in the request to this action, soredirect_to :back
could not be called successfully. If this is a test, make sure to specifyrequest.env["HTTP_REFERER"]
.
How do I go about setting the HTTP_REFERER
in my test?
回答1:
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
回答2:
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
回答3:
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
回答4:
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
回答5:
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.
回答6:
request.env['HTTP_REFERER'] = '/your_referring_url'
来源:https://stackoverflow.com/questions/6040479/rspec-testing-redirect-to-back