--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
相关产品推荐
相关产品推荐

