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

--breakpoint标志改变mix test结合Bypass的行为问题排查

问题解答

1. 原因分析

直接运行mix test时,测试进程执行完Manager.login(credentials, false)后会立即结束。由于你的项目采用异步进程通信机制,Manager.login发起的HTTP请求是异步执行的,测试进程退出时,异步请求还没来得及发送到Bypass,导致Bypass检测不到请求。

而用iex -S mix test --breakpoints手动调用时,测试进程处于断点暂停状态,有足够的时间让异步请求完成并到达Bypass,因此测试能通过。

2. 修复方案

方案一:等待异步操作完成(推荐,适配项目异步设计)

由于项目内通过进程send传递消息,Manager.login应该会向调用进程(测试进程)发送结果消息。在测试中添加消息接收逻辑,等待登录操作的异步回调完成后再结束测试:

test "logs in user correctly", %{bypass: bypass, credentials: credentials} do
  Bypass.expect_once(bypass, fn conn ->
    IO.inspect(conn.request_path, label: "REQ PATH")
    IO.inspect(conn.method, label: "METHOD")
    Plug.Conn.resp(conn, 429, ~s<{"errors": [{"code": 88, "message": "Rate limit exceeded"}]}>)
  end)

  # 启动应用
  _manager_pid = start_link_supervised!(ManagerSupervisor)
  
  # 发起异步登录请求
  Manager.login(credentials, false)

  # 等待异步消息(根据实际消息格式调整)
  receive do
    {:login_result, _result} -> :ok
  after
    5000 -> flunk("Timeout waiting for login result")
  end
end

方案二:使用Bypass的等待函数

如果不需要处理登录结果,也可以直接用Bypass提供的wait_for_requests函数,等待指定数量的请求到达:

test "logs in user correctly", %{bypass: bypass, credentials: credentials} do
  Bypass.expect_once(bypass, fn conn ->
    IO.inspect(conn.request_path, label: "REQ PATH")
    IO.inspect(conn.method, label: "METHOD")
    Plug.Conn.resp(conn, 429, ~s<{"errors": [{"code": 88, "message": "Rate limit exceeded"}]}>)
  end)

  # 启动应用
  _manager_pid = start_link_supervised!(ManagerSupervisor)
  
  # 发起登录请求
  Manager.login(credentials, false)

  # 等待1个请求到达,超时5秒
  assert Bypass.wait_for_requests(bypass, 1, 5000)
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:15:55