无法在 Rails 5 控制器测试中设置会话哈希
Unable to set session hash in Rails 5 controller test
根据 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: undefined method `session' for nil:NilClass
这也失败了:
test "some thing" do
get '/login', nil, nil, { user_id: users(:stephen).id }
# etc
end
会话哈希被忽略,并且出现关于 rails 仅接受 4 个不同命名参数的弃用警告。
还有其他人在使用 Rails 5.rc1 时遇到这种问题吗?
尝试通过open_session
方法设置session
open_session do |sess|
sess.get "/login", user_id: users(:stephen).id
assert_redirected_to root_url, 'Expected redirect to root'
end
事实证明,控制器测试现在默认继承自 ActionDispatch::IntegrationTest
,而 handles the behaviour I wanted 的代码位于 ActionController::TestCase
中。
所以现在的解决方法是执行以下操作:
1 - 修改您的控制器测试以继承自 ActionController::TestCase
class SessionsControllerTest < ActionController::TestCase
2 - 修改所有 http 请求调用以使用符号化操作名称而不是 url:
# 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 带我找到答案
我想你可以这样做:
delete cart_url(@cart), params: { 'session' => { :cart_id => @cart.id }}
在 Rails 5 中不再可能在控制器测试中访问会话: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
..
根据 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: undefined method `session' for nil:NilClass
这也失败了:
test "some thing" do
get '/login', nil, nil, { user_id: users(:stephen).id }
# etc
end
会话哈希被忽略,并且出现关于 rails 仅接受 4 个不同命名参数的弃用警告。
还有其他人在使用 Rails 5.rc1 时遇到这种问题吗?
尝试通过open_session
方法设置session
open_session do |sess|
sess.get "/login", user_id: users(:stephen).id
assert_redirected_to root_url, 'Expected redirect to root'
end
事实证明,控制器测试现在默认继承自 ActionDispatch::IntegrationTest
,而 handles the behaviour I wanted 的代码位于 ActionController::TestCase
中。
所以现在的解决方法是执行以下操作:
1 - 修改您的控制器测试以继承自 ActionController::TestCase
class SessionsControllerTest < ActionController::TestCase
2 - 修改所有 http 请求调用以使用符号化操作名称而不是 url:
# 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 带我找到答案
我想你可以这样做:
delete cart_url(@cart), params: { 'session' => { :cart_id => @cart.id }}
在 Rails 5 中不再可能在控制器测试中访问会话: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
..