--断点标志改变使用旁路混合测试的行为

问题描述 投票:0回答:1

背景

我正在尝试对我正在编写的简单终端应用程序进行集成测试。 这个应用程序基本上是一个主管,它监督其他较小的库。

项目内的通信大多是异步的,进程

send
向调用者发送消息。

问题

我进行的其中一个测试需要 HTTP 请求,因此我决定使用

bypass
来实现此目的。然而,这个问题却令我感到惊讶。这是测试:

    setup do
      bypass = Bypass.open(port: 8082)
      credentials = %{email: "an_email", pass: "a_password"}

      %{
        credentials: credentials,
        bypass: bypass
      }
    end


  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)

     # start the application
      _manager_pid = start_link_supervised!(ManagerSupervisor)
      
       # this should make a GET request to bypass but ...
       Manager.login(credentials, false)
    end

如果我只是运行

mix test
这个简单的测试就会失败,因为 Bypass 没有收到任何请求。

1) test login logs in user correctly (Manager.WorkerTest)
     test/integration/manager_test.exs:83
     No HTTP request arrived at Bypass

混乱

但是,令人困惑的是,如果我通过运行

--breakpoints
使用
 iex -S mix test --breakpoints
功能,我可以通过执行一些简单的步骤来使测试通过:

  • 逐行按
    n
  • 当到达最后一行(
    Manager.login(credentials, false
    )时,我不使用
    n
    c
    执行它。相反,我手动输入命令
    Manager.login(credentials, false)
  • 已拨打
    bypass
    电话
  • 然后我按
    c
    ,测试通过了

这让我很困惑。看来测试过程没有调用

Manager.login
,就像它应该的那样。

我无法解释这一点。

问题

  1. 为什么当我使用
    bypass
    选项手动调用
    Manager.login
    时会调用
    --breakpoint
    ,而不是在
    mix test
    运行时调用?
  2. 我该如何修复我的测试?
testing elixir bypass
1个回答
0
投票

解决方案

经过更多调查,我意识到运行测试的测试过程完成得太快。事实证明,绕过 http 请求以及代码必须执行的其他 IO 任务的延迟时间太长,因此测试将在运行测试的进程收到任何消息之前结束。

为此,即使@Peaceful James使用

Process.sleep
的建议可行,我还是决定采用不同的方法,使用
assert_receive
,它确实有一个超时选项,它强制测试进程等待设定的时间,然后如果没有收到接收给定模式的消息,则显示进程的整个邮箱。

最终测试看起来像这样:


  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)

     # start the application
      _manager_pid = start_link_supervised!(ManagerSupervisor)
      
       # this should make a GET request to bypass but ...
       Manager.login(credentials, false)
       
       assert_receive({:login, :ok}, 5000) # 5 secs timeout
    end

原始解决方案的来源可以在这篇文章中找到:

https://elixirforum.com/t/breakpoint-flag-changes-the-behaviour-of-mix-test-using-bypass/67138/2?u=fl4m3ph03n1x

© www.soinside.com 2019 - 2024. All rights reserved.