#ruby-on-rails #redirect #rspec #rspec2
#ruby-on-rails #перенаправление #rspec #rspec2
Вопрос:
Как вы тестируете redirect_to :back
в rspec?
Я получаю
ActionController::RedirectBackError
: В запросе на это действие было задано
NoHTTP_REFERER
, поэтомуredirect_to :back
не удалось успешно вызвать. Если это тест, обязательно укажитеrequest.env["HTTP_REFERER"]
.
Как мне настроить HTTP_REFERER
в моем тесте?
Комментарии:
1. Возможно, было бы полезно посмотреть сам тестовый источник. Это может быть симптомом другой проблемы…
2. Я смог устранить эту ошибку, сначала вызвав ‘visit root_path’. Но я думаю, что могу сделать это только в интеграционном тестировании. Это верно?
Ответ №1:
Используя RSpec, вы можете установить ссылку в before
блоке. Когда я попытался установить referer непосредственно в тесте, это, похоже, не сработало, независимо от того, куда я его поместил, но блок before делает свое дело.
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
Комментарии:
1. Я обнаружил, что это хорошая идея использовать:
request.env["HTTP_REFERER"] = "where_i_came_from" unless request.nil? or request.env.nil?
2. да. для меня это всегда ноль, и это просто не работает. Для меня это выглядит как огромная ошибка.
3. Возможно, он был обновлен для устранения этой проблемы с момента создания этого ответа, но я могу успешно установить
request.env["HTTP_REFERER"]
в своем тесте без использованияbefore
блока.
Ответ №2:
Из руководства rails при запросе запроса с новым стилем запроса:
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:
Если кто-то наткнется на это, и они используют request
спецификации, вам нужно будет явно задать заголовки в выполняемом вами запросе. Формат тестового запроса зависит от того, какую версию RSpec вы используете, и можете ли вы использовать аргументы ключевого слова вместо аргументов позиции.
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:
ИМХО, принятый ответ немного взламывает. Лучшей альтернативой было бы установить HTTP_REFERER
фактический URL в вашем приложении, а затем ожидать, что он будет перенаправлен обратно:
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
- Перенаправление на случайную строковую константу выглядит так, как будто оно работает случайно
- Вы используете преимущества встроенной функциональности rspec, чтобы выразить именно то, что вы хотели
- Вы не вводите и не повторяете значения magic string
Для более новых версий rspec вместо этого вы можете использовать ожидания:
expect(response).to redirect_to :back
Ответ №5:
Что касается тестирования: обратные ссылки в интеграционных тестах, я сначала посещаю конечную страницу, которая, как я думаю, вряд ли когда-либо будет использоваться в качестве ссылки, а затем страницу, которую я тестирую. Итак, мой код выглядит следующим образом
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
Однако у этого есть недостаток, заключающийся в том, что если ссылка действительно на deadend_path, то тест будет пройден неправильно.
Ответ №6:
request.env['HTTP_REFERER'] = '/your_referring_url'