Unable to set session hash in Rails 5 controller test

故事扮演 提交于 2019-12-28 22:03:33

问题


According to the Rails Edge Guide all ActionDispatch::IntegrationTest HTTP requests take optional named keyword arguments:

get post_url, params: { id: 12 }, session: { user_id: 5 }

Great. Now, I've got the following code in a controller test:

test 'should redirect from login page if user is logged in' do
  get '/login', session: { user_id: users(:stephen).id }
  assert_redirected_to root_url, 'Expected redirect to root'
end

And when I run it, my test fails and I see the following deprecation warning:

ActionDispatch::IntegrationTest HTTP request methods will accept only
the following keyword arguments in future Rails versions:
params, headers, env, xhr

So obviously it's rails is not letting me pass a keyword argument named session.

Furthermore, both of the old methods of setting the session in a functional test no longer work either:

test "some thing" do
  session[:user_id] = users(:stephen).id
  # etc
end

NoMethodError: undefined method `session' for nil:NilClass

And this fails too:

test "some thing" do
  get '/login', nil, nil, { user_id: users(:stephen).id }
  # etc
end

The session hash is just ignored and the deprecation warning about rails only accepting 4 different named arguments appears.

Is anyone else having this sort of trouble with Rails 5.rc1?


回答1:


In Rails 5 it is no longer possible to access session in controller tests: http://blog.napcs.com/2016/07/03/upgrading-rails-5-controller-tests/. The suggestion is to access the controller method that would set the appropriate session value for you. This comment shows and example of how you might work around this limitation: https://github.com/rails/rails/issues/23386#issuecomment-192954569

  # helper method
  def sign_in_as(name)
    post login_url, params: { sig: users(name).perishable_signature )
  end

class SomeControllerTest
  setup { sign_in_as 'david' }

  test 'the truth' do
  ..



回答2:


Try set session through open_session method

open_session do |sess|
  sess.get "/login", user_id: users(:stephen).id
  assert_redirected_to root_url, 'Expected redirect to root'
end



回答3:


It turns out that controller tests now inherit from ActionDispatch::IntegrationTest by default and the code that handles the behaviour I wanted sits in ActionController::TestCase.

So the fix for now is to do the following:

1 - modify your controller test to inherit from ActionController::TestCase

class SessionsControllerTest < ActionController::TestCase

2 - modify all of your http request calls to use symbolized action names instead of urls:

# so change this
get login_url

# to this
get :new

And then you should be able to use the new kw_args in your requests like so:

# now this will work fine
get :new, session: { user_id: user.id }

# and so will this
session[:user_id] = user.id

I'm going to open an issue on github later on as I imagine this behaviour is not intended. Thanks to @BoraMa for leading me to the answer




回答4:


I think you can do as this:

delete cart_url(@cart), params: { 'session' => { :cart_id => @cart.id }}


来源:https://stackoverflow.com/questions/37796129/unable-to-set-session-hash-in-rails-5-controller-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!