You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7.0.4 API应用使用Devise测试时触发DisabledSessionError

解决Rails API模式下MiniTest使用Devise sign_in的会话错误

针对你遇到的问题,核心原因是Rails API模式默认禁用会话存储,而Devise的sign_in方法依赖会话保存登录状态,测试环境下就会触发DisabledSessionError。以下是几种可行的解决方案:

方案1:直接设置current_user(最简单)

跳过Devise的sign_in流程,直接给控制器实例赋值current_user,模拟登录状态:

修改测试代码:

test "should get index" do
  # 直接设置当前登录用户
  @controller.instance_variable_set(:@current_user, users(:one))
  get movies_url, as: :json
  assert_response :success
end

如果多个测试都需要用,可以封装成辅助方法,在test/test_helper.rb中添加:

module ControllerTestHelper
  def sign_in_api(user)
    @controller.instance_variable_set(:@current_user, user)
  end
end

class ActiveSupport::TestCase
  include ControllerTestHelper
end

之后测试里直接调用:

test "should get index" do
  sign_in_api users(:one)
  get movies_url, as: :json
  assert_response :success
end

方案2:测试环境启用会话存储(适合坚持用Devise sign_in的场景)

如果必须使用Devise的sign_in方法,需要在测试环境中启用会话中间件:

  1. 在config/environments/test.rb中添加会话配置:
config.session_store :cookie_store, key: '_cinema_app_session'
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
  1. 在config/initializers/devise.rb中调整会话跳过设置:
# 只跳过HTTP认证和Token认证的会话存储,允许测试环境使用会话
config.skip_session_storage = [:http_auth, :token_auth]

这种方法会在测试环境中启用会话,可能和API模式的无状态设计冲突,仅推荐特殊场景使用。

方案3:模拟API真实认证方式(最贴合生产场景)

如果你的API实际使用Token认证,测试时直接在请求头中携带认证Token:

  1. 确保用户Fixture包含认证Token(test/fixtures/users.yml):
one:
  email: admin@cinema.com
  encrypted_password: <%= Devise.bcrypt(User, 'admin123') %>
  authentication_token: 'cinema-admin-token-001'
  1. 测试代码中携带Token请求:
test "should get index" do
  auth_token = users(:one).authentication_token
  get movies_url, 
      as: :json, 
      headers: { 'Authorization' => "Token token=#{auth_token}" }
  assert_response :success
end

这种方式完全贴合API的无状态认证逻辑,是最推荐的长期解决方案。

内容的提问来源于stack exchange,提问作者Victor Rubia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:50:26