开发者

Rspec - Rails - How to follow a redirect

Does anyone know how to make rspec follow a redirect (in a controller spec)? (e.g test/unit has follow_redirect!)

I have tried "follow_redirect!" and "fol开发者_Python百科low_redirect" but only get

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

For example:

When I create an account the page is redirected to accounts page and my new account should be at the top of the list.

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

But FOLLOW_REDIRECT! needs to be changed to something that actually works.


I think this is the default behavior for rspec-rails controller tests, in the sense that you can set an expectation on the response status and/or path, and test for success.

For example:

it "should create an account" do
  post :create
  response.code.should == "302"
  response.should redirect_to(accounts_path)
end


You can access the redirect location with

response.headers['Location']

you could then request that directly.


If you want to test the redirect you are moving outside of the rspec-rails domain.

You can use Webrat or some other integration-test framework to test this.

The easiest way to solve this without resorting to integration testing is probably to mock out the method that is causing the redirect.


The spec is out of scope, if you want to follow a redirect use request spec, the equivalent of integration test in Test::Unit.

In request specs follow_redirect! works as well as in Test::Unit.

Or if you want to redirect inmediately use _via_redirect as suffix for the verb, example:

post_via_redirect :create, user: @user


Try to use integration/request tests. They are using web-like acces through routing to controllers. For example: I have for Rails 2 app in file /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

and it works. Until you want to send headers (for basic http authorization).

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

is fine for create, but after redirection it returns 401 and needs new authorization. SO I have to split it in 2 tests: creation and show on result of creation.


For RSpec / Capybara + Rails

response_headers['Location']

But it works only if there is no delay before redirect. If it is there, then it's harder to follow the logic.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜