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

Elixir/Phoenix/Guardian测试中为conn分配current_user不生效问题

为什么给Conn分配的current_user在测试中没生效?

我来帮你捋捋这个问题——你遇到的核心问题是控制器里的模式匹配写错了,导致根本没法正确匹配到带有current_user的Conn实例。

先看你控制器里的第一个函数子句:

def index(%{assigns: %{current_user: %User{} = current_user}}} = conn, params) do
  ## 用户已存在
end

这里的坑在于:Phoenix里的conn是Plug.Conn结构体,不是普通的Map。你用%{assigns: ...} = conn这种方式做模式匹配时,Elixir会把它当成普通Map来匹配,但结构体的模式匹配必须显式指定结构体模块名,不然匹配肯定会失败。

所以这个子句永远不会被命中,不管你测试里有没有给conn assign current_user,代码都会直接落到第二个没有模式限制的index函数里,这就是你看到conn.assigns.current_user为nil的原因。

解决办法

把第一个函数子句的模式匹配改成针对Plug.Conn结构体的写法就行:

def index(%Plug.Conn{assigns: %{current_user: %User{} = current_user}} = conn, params) do
  ## 用户已存在
end

这样就能正确匹配到带有current_user的Conn实例了。如果不需要直接使用current_user变量,还可以简化成:

def index(%Plug.Conn{assigns: %{current_user: %User{}}}, params) do
  ## 用户已存在
end

测试小建议

你还可以在测试里加个断言,直观验证修改是否生效:

test "GET /posts", %{conn: conn} do
  user = insert(:user)
  conn = assign(conn, :current_user, user)
  conn = get(conn, post_path(conn, :index))
  # 替换成你第一个子句返回的响应内容
  assert html_response(conn, 200) =~ "专属已登录用户的内容"
end

内容的提问来源于stack exchange,提问作者Peter R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:26:20