Phoenix控制器测试丢失current_user会话问题求助
解决Phoenix测试中登录会话状态丢失的问题
我一眼就看出问题出在哪了——你现在的setup只是手动给初始conn assign 了current_user,但这没法在测试的多个请求之间保留会话状态!原因很简单:Phoenix里每次发起测试请求(比如get/2、post/2)都会生成一个全新的conn对象,而且你的认证逻辑大概率是从**会话(session)**中读取用户身份,而不是直接依赖conn.assigns里的值。手动assign的current_user不会被自动带入新的请求conn,自然就出现了会话丢失的情况。
修正你的Setup代码
你需要在setup里模拟真实的登录流程,把用户身份存入会话,让认证中间件能在后续请求中自动识别用户。这里分两种常见情况给出解决方案:
情况1:基于Session的简单认证
如果你的认证是通过会话中的:user_id来获取用户的,修改setup如下:
setup %{conn: conn} = config do if username = config[:login_as] do user = insert_user(username: username) # 将用户ID存入会话,并刷新会话确保生效 conn = conn |> put_session(:user_id, user.id) |> configure_session(renew: true) {:ok, conn: conn, user: user} else :ok end end
情况2:使用Guardian等认证库
如果项目用了Guardian这类JWT/会话认证库,直接用库提供的方法来设置登录状态:
setup %{conn: conn} = config do if username = config[:login_as] do user = insert_user(username: username) # 用Guardian的Plug方法设置登录会话 conn = Guardian.Plug.sign_in(conn, user) {:ok, conn: conn, user: user} else :ok end end
测试中的关键注意点
在测试用例里,每次请求后一定要使用返回的新conn发起下一个请求,这样会话状态才会被持续保留:
test "登录后访问多个页面", %{conn: conn, user: user} do # 第一次请求,获取带会话的新conn conn = get(conn, "/dashboard") assert html_response(conn, 200) =~ "欢迎回来,#{user.username}" # 用新的conn发起下一个请求,会话状态会保留 conn = get(conn, "/profile") assert html_response(conn, 200) =~ "个人资料" end
这样修改后,无论测试里有多少个断言和请求,登录状态都能稳定保持啦!
内容的提问来源于stack exchange,提问作者thyago stall
相关产品推荐
相关产品推荐

