Rspec - Rails - Как следовать перенаправлению

Кто-нибудь знает, как заставить rspec следовать перенаправлению (в спецификации контроллера)? (например, у теста/модуля есть follow_redirect!)

Я пробовал "follow_redirect!" и "follow_redirect", но получают только

undefined method `follow_redirect!' for #<Spec::Rails::Example::ControllerExampleGroup::Subclass_1:0xb6df5294>

Например:
Когда я создаю учетную запись, страница перенаправляется на страницу учетных записей, и моя новая учетная запись должна быть вверху списка.

it "should create an account" do
  post :create, :name => "My New Account"
  FOLLOW_REDIRECT!
  response.code.should == "200"
  accounts = assigns[:accounts]
  accounts[0].name.should == "My New Account"
end

Но FOLLOW_REDIRECT! необходимо заменить на то, что действительно работает.


person Jonas Söderström    schedule 19.05.2010    source источник


Ответы (6)


Если вы хотите протестировать перенаправление, вы перемещаетесь за пределы домена rspec-rails.

Вы можете использовать Webrat или какую-либо другую среду интеграционного тестирования, чтобы проверить это.

Самый простой способ решить эту проблему, не прибегая к интеграционному тестированию, — вероятно, смоделировать метод, вызывающий перенаправление.

person andersjanmyr    schedule 20.05.2010
comment
я думаю, что этот ответ неверен, правильный ответ от zetetic - person jpw; 23.12.2012
comment
На самом деле этот ответ правильный, а мой нет. В моем ответе показано только, как проверить, происходит ли перенаправление - OP спросил, как проверить содержимое ответа после выполнения перенаправления. - person zetetic; 20.03.2013

Я думаю, что это поведение по умолчанию для тестов контроллера rspec-rails в смысл, что вы можете установить ожидание в отношении статуса ответа и / или пути и проверить его на успех.

Например:

it "should create an account" do
  post :create
  response.code.should == "302"
  response.should redirect_to(accounts_path)
end
person zetetic    schedule 20.05.2010
comment
Привет Зететик. Спасибо за ответ. То, что вы описываете в своем ответе, будет правильным способом проверки того, что ответ является перенаправлением 302 на account_path. Что я хочу сделать, так это выполнить перенаправление на account_path и проверить поведение этой страницы. Например. убедитесь, что моя новая учетная запись указана там. - person Jonas Söderström; 20.05.2010
comment
Я обновил свой вопрос, надеюсь, вы не возражаете, что я позаимствовал ваш пример. - person Jonas Söderström; 20.05.2010
comment
Думаю, я неправильно понял вопрос. Поможет ли integrate_views в этой ситуации? - person zetetic; 20.05.2010
comment
integrate_views не помогает. Я все еще получаю ответ "Вас перенаправляют...", но это была хорошая попытка. - person Jonas Söderström; 20.05.2010
comment
Теперь я могу проверить, что редирект сработал. Но это не то, что я ищу. Я хочу, чтобы rspec автоматически следовал за перенаправлениями, и я хочу иметь успех/ошибку на перенаправленной странице. Это важно, если вы тестируете контроллер, который обеспечивает https. В таком случае я даже не покидаю свой домен. Любая мысль, как это сделать? - person Robert Reiz; 16.07.2012
comment
Этот ответ касается этого: stackoverflow.com/a/2874007/17410. Капибара - хороший выбор. - person zetetic; 16.07.2012
comment
Что касается RSpec3.1, он предпочитает следующий синтаксис: expect(response).to redirect_to(accounts_path) см. также - relishapp.com/rspec/rspec-rails/docs/matchers/ - person Nobu; 01.12.2014

Вы можете получить доступ к местоположению перенаправления с помощью

response.headers['Location']

вы могли бы запросить это напрямую.

person toonsend    schedule 26.09.2012
comment
Это единственный прямой ответ на ОП. Другие указывают, что следует сделать, но это единственное, что говорит о том, как сделать то, что запрашивается. Это полезно, если кто-то приходит сюда из запроса Google, как я. - person Jonathan Geisler; 30.04.2014
comment
Это будет работать, но обязательно объявите response.params, если есть. Например, может быть, я хочу проверить, что моя переадресация отображает конкретное флэш-сообщение. тестирование GET response.headers['Location'] в одиночку не поможет. - person Jesse Novotny; 17.06.2017

Спецификация выходит за рамки, если вы хотите следовать спецификации запроса на перенаправление, эквивалентной интеграционному тесту в Test::Unit.

В спецификациях запроса follow_redirect! работает так же, как и в Test::Unit.

Или, если вы хотите сразу перенаправить, используйте _via_redirect в качестве суффикса для глагола, например:

post_via_redirect :create, user: @user
person Carlos Esteban Lopez Jaramillo    schedule 18.06.2015
comment
Это возвращает undefined local variable or method 'post_via_redirect' Я делаю что-то не так? Где бы вы назвали этот метод? - person Jesse Novotny; 19.06.2017
comment
Загляните в follow_redirect!, согласно документации, post_via_redirect устарел. - person SomeDudeSomewhere; 27.04.2018

Попробуйте использовать интеграционные/запросные тесты. Они используют веб-доступ через маршрутизацию к контроллерам. Например: у меня есть приложение для Rails 2 в файле /spec/integration/fps_spec.rb

 require 'spec_helper'

 describe "FinPoradci" do 

   it "POST /fps.html with params" do
     fp_params={:accord_id => "FP99998", :under_acc => "OM001", :first_name => "Pavel", :last_name => "Novy"}
     fp_test=FinPoradce.new(fp_params)
     #after create follow redirection to show
     post_via_redirect "/fps", {:fp => fp_params}
     response.response_code.should == 200 # => :found ,  not 302 :created
     new_fp=assigns(:fp)
     new_fp.should_not be_empty
     new_fp.errors.should be_empty
     flash[:error].should be_empty
     flash[:notice].should_not be_empty
     response.should render_template(:show)
   end
 end

и это работает. Пока вы не захотите отправлять заголовки (для базовой http-авторизации).

 env={'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user,password)}
 post_via_redirect "/fps", {:fp => fp_params}, env

подходит для создания, но после перенаправления он возвращает 401 и требует новой авторизации. Поэтому я должен разделить его на 2 теста: создание и отображение результата создания.

person Foton    schedule 17.04.2013

Для RSpec / Capybara + Rails

response_headers['Location']

Но это работает только если нет задержки перед редиректом. Если она есть, то логике следовать сложнее.

person Vjatseslav Gedrovits    schedule 21.02.2013
comment
это не определено, но response.headers['Location'] работает - person Jesse Novotny; 19.06.2017