无法在Rails 5控制器测试中设置会话哈希

时间:2016-06-13 17:49:20

标签: ruby-on-rails ruby-on-rails-5

根据Rails Edge Guide所有ActionDispatch :: IntegrationTest HTTP请求采用可选的命名关键字参数:

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

大。现在,我在控制器测试中得到以下代码:

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

当我运行它时,我的测试失败,我看到以下弃用警告:

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

很明显,它的rails不允许我传递一个名为 session 的关键字参数。

此外,在功能测试中设置会话的两种旧方法都不再有效:

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

NoMethodError:nil的未定义方法`session':NilClass

这也失败了:

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

会话哈希被忽略,并且关于rails的弃用警告仅接受4个不同的命名参数。

是否有其他人在使用Rails 5.rc1时出现此类问题?

4 个答案:

答案 0 :(得分:12)

在Rails 5中,不再可能在控制器测试中访问会话:http://blog.napcs.com/2016/07/03/upgrading-rails-5-controller-tests/。建议是访问为您设置适当会话值的控制器方法。此评论显示了您如何解决此限制的示例: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
  ..

答案 1 :(得分:1)

尝试设置sessionopen_session方法

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

答案 2 :(得分:1)

事实证明,控制器测试现在默认继承自ActionDispatch::IntegrationTest,而handles the behaviour I wanted代码位于ActionController::TestCase

所以现在的解决方法是执行以下操作:

1 - 修改您的控制器测试以继承ActionController :: TestCase

class SessionsControllerTest < ActionController::TestCase

2 - 修改所有http请求调用以使用符号化操作名称而不是urls:

# so change this
get login_url

# to this
get :new

然后您应该可以在请求中使用新的kw_args,如下所示:

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

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

我打算稍后在github上打开一个问题,因为我想这个行为并不打算。感谢@BoraMa带领我回答

答案 3 :(得分:-1)

我认为你可以这样做:

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