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

使用Guardian进行控制器测试:已认证路由请求授权问题

我来帮你搞定带认证的API控制器测试问题!看起来你已经有了基础的测试结构,但还没处理请求的授权逻辑,下面分步骤给你调整方案:

第一步:在Setup中添加认证逻辑

Phoenix的setup块会在每个测试用例执行前运行,正好用来处理认证,这样每个测试拿到的conn都是已经授权过的。根据你的认证方式(JWT/Session/API Key),选择对应的实现:

情况1:JWT认证(最常见的API认证方式)

假设你有用户创建和JWT生成的函数,修改setup如下:

# 先定义测试用的用户属性(放在测试模块顶部)
@user_attrs %{email: "test_league_user@example.com", password: "secure_password123"}
@valid_attrs %{name: "Test Premier League", description: "A test football league"}

setup %{conn: conn} do
  # 1. 创建测试用户
  {:ok, user} = YourApp.Accounts.create_user(@user_attrs)
  # 2. 生成用户的JWT token(替换成你项目里的token生成函数)
  token = YourApp.Accounts.generate_auth_token(user)
  # 3. 给conn设置必要的请求头:Accept + Authorization Bearer token
  authorized_conn = 
    conn
    |> put_req_header("accept", "application/json")
    |> put_req_header("authorization", "Bearer #{token}")
  
  {:ok, conn: authorized_conn, user: user}
end

情况2:Session认证(适合前后端同构的Phoenix应用)

如果你的认证是基于Session的,就先模拟登录请求拿到带认证Session的conn:

setup %{conn: conn} do
  {:ok, user} = YourApp.Accounts.create_user(@user_attrs)
  # 模拟登录请求,获取认证后的conn
  authorized_conn = 
    conn
    |> put_req_header("accept", "application/json")
    |> post(YourApp.Router.Helpers.session_path(conn, :create), 
           user: %{email: user.email, password: @user_attrs.password})
    |> recycle() # 重置conn状态,保留Session信息
  
  {:ok, conn: authorized_conn, user: user}
end

情况3:API Key认证

如果是用固定API Key的简单认证,直接在请求头里加Key即可:

setup %{conn: conn} do
  authorized_conn = 
    conn
    |> put_req_header("accept", "application/json")
    |> put_req_header("x-api-key", "your_test_api_key_here")
  
  {:ok, conn: authorized_conn}
end

第二步:修改你的测试用例

现在每个测试拿到的conn已经是授权过的了,直接用它发起请求就行:

test "creates and renders resource when data is valid", %{conn: conn} do
  conn = post(conn, YourApp.Router.Helpers.league_path(conn, :create), league: @valid_attrs)
  # 断言返回201创建成功状态码
  assert json_response(conn, 201)["data"]["name"] == @valid_attrs.name
  # 可以根据你的API返回结构添加更多断言
end

额外:测试未认证的场景

别忘了测试未授权请求的情况,确保你的认证拦截逻辑正常:

test "returns 401 Unauthorized when not authenticated", %{conn: conn} do
  # 创建一个未认证的干净conn
  unauthed_conn = put_req_header(conn, "accept", "application/json")
  conn = post(unauthed_conn, YourApp.Router.Helpers.league_path(conn, :create), league: @valid_attrs)
  
  assert json_response(conn, 401)["error"] == "Unauthorized"
end

这样就能完整覆盖认证路由的控制器测试啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:33:16