Тестирование Rspec redirect_to :назад

Как вы тестируете redirect_to :back в rspec?

я получил

ActionController::RedirectBackError:
В запросе на это действие не было указано HTTP_REFERER, поэтому redirect_to :back не удалось успешно вызвать. Если это тест, обязательно укажите request.env["HTTP_REFERER"].

Как мне настроить HTTP_REFERER в моем тесте?


person Cyrus    schedule 18.05.2011    source источник
comment
Может быть полезно увидеть сам тестовый источник. Это может быть симптомом другой проблемы...   -  person jaydel    schedule 18.05.2011
comment
Я смог устранить эту ошибку, сначала вызвав «visit root_path». Но я думаю, что могу сделать это только в интеграционном тесте. Это правильно?   -  person Cyrus    schedule 19.05.2011


Ответы (5)


Используя RSpec, вы можете установить реферер в блоке before. Когда я попытался установить реферер непосредственно в тесте, он, похоже, не работал независимо от того, где я его разместил, но блок 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
person jrh    schedule 18.07.2011
comment
Я обнаружил, что было бы неплохо использовать: request.env["HTTP_REFERER"] = "where_i_came_from" unless request.nil? or request.env.nil? - person jcollum; 14.01.2012
comment
Ага. для меня это всегда ноль и просто не работает. Выглядит как огромный баг для меня. - person Robert Reiz; 08.08.2013
comment
Возможно, он был обновлен, чтобы решить эту проблему с момента создания этого ответа, но я могу успешно установить request.env["HTTP_REFERER"] в своем тесте без использования блока before. - person Nick; 13.04.2016

Из rails guide при запросе запроса с новым стилем запроса:

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
person ivanxuu    schedule 21.10.2016

Если кто-то наткнется на это и использует спецификации 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

person sp89    schedule 20.07.2017

ИМХО принятый ответ немного хакерский. Лучшей альтернативой было бы установить 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, чтобы выразить именно то, что вы хотели
  • Вы не вводите и не повторяете магические строковые значения

Для более новых версий rspec вы можете вместо этого использовать ожидания:

expect(response).to redirect_to :back
person ndnenkov    schedule 18.04.2016

Что касается тестирования ссылок :back в интеграционных тестах, я сначала посещаю тупиковую страницу, которая, как я думаю, вряд ли когда-либо будет использоваться в качестве ссылки, а затем страницу, которую я тестирую. Итак, мой код выглядит так

   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, то тест будет пройден неправильно.

person Obromios    schedule 23.05.2012