Rspec请求测试调用OmniAuth登出未触发destroy方法问题
问题解答
1. 未登录用户访问登出路由为何返回「成功」状态?
Devise 的默认设计是:未登录状态下访问登出接口不会抛出权限错误(如401/403),而是直接执行「无操作」的登出流程,最终返回302重定向到配置的登出后默认路径(默认是root_path)。
你测试里用expect(response).to be_successful是错误的——be_successful仅匹配2xx状态码,而重定向是3xx状态码。正确的断言应该是验证重定向行为,比如:
expect(response).to redirect_to(root_path) # 替换成你的实际登出跳转路径
2. 自定义destroy方法未被调用时,实际执行的是什么?
首先纠正:你的自定义destroy方法大概率被调用了,但因为测试场景的问题导致你误以为没执行。核心问题出在两个点:
- 测试中用户未登录:Devise 的
sign_out方法在未登录状态下会返回false,后续直接触发重定向,但你的cookies.delete 'visited'代码是在super之前执行的,理论上应该已经删除了 Cookie。 - 测试断言的对象错误:在 RSpec 请求测试中,
cookies对象是请求发送时的 Cookie Jar,而服务器删除 Cookie 是通过响应头Set-Cookie来实现的,你需要从response.cookies中获取结果,而不是直接用cookies。
修改测试中的断言即可验证:
expect(response.cookies['visited']).to be_nil
另外,如果你想确保destroy方法在登录状态下被正确执行,需要先在测试中登录用户:
before(:each) do sign_in user # 先登录用户 cookies['visited'] = '1' end
这样既能验证登录状态下的登出逻辑,也能确保自定义destroy方法的代码被完整执行。
内容的提问来源于stack exchange,提问作者NganCun
相关产品推荐
相关产品推荐

