gpt4 book ai didi

elixir - Elixir 中测试主管的最佳实践

转载 作者:行者123 更新时间:2023-12-04 19:03:13 31 4
gpt4 key购买 nike

我在谷歌上搜索了很多,但找不到任何关于这个主题的东西——要么 Elixir 的语言太年轻,要么我用错误的术语搜索。

我正在学习 Jose Valim 的 Elixir Portal 教程 (https://howistart.org/posts/elixir/1) 并正在构建实践测试(我已经构建了所有功能)。

本教程的一部分是构建一个 Supervisor 以使 Portal.Door 模块具有容错性。

我正在尝试使用以下代码测试容错性(例如,如果 Portal.Door 实例未正确关闭,Supervisor 将重新启动它)

defmodule PortalTest do
use ExUnit.Case, async: true

...

test "supervisor restarts doors" do
{:ok, pid} = Portal.shoot(:third)
Process.unlink(pid)
Process.exit(pid, :shutdown)
assert Portal.Door.get(:third) == [] #new doors initialize with an empty array
end

end

但是当我运行测试时,我不断收到这个错误:
  1) test supervisor restarts doors (PortalTest)
test/portal_test.exs:35
** (exit) exited in: GenServer.call(:third, {:get, #Function<3.47016826/1 in Portal.Door.get/1>}, 5000)
** (EXIT) shutdown
stacktrace:
(elixir) lib/gen_server.ex:356: GenServer.call/3
test/portal_test.exs:39

所以,我想知道是否有更好的方法来做到这一点,或者我的代码很糟糕。

最佳答案

Process.exit/1发送退出信号但不等待进程停止。从您的错误输出来看,它看起来像 Portal.Door.get/1 then 失败,因为 gen_server 进程在收到调用消息之前终止。

为了克服这个问题,您需要等待进程关闭,然后再次重新启动。一个简单的补救措施可能是通过 :timer.sleep/1 短暂 sleep (比如 100 毫秒)。发出退出信号后。

更复杂的方法是等待进程终止,然后再次重新启动。第一部分可以通过设置监视器轻松完成(通过 Process.monitor/1 )并等待相应的 :DOWN信息。通过这样做,您还可以验证目标进程确实已终止。

然后需要等待进程再次重启,才能发出请求。这可能很棘手,并且睡一小会儿可能是最简单的选择。或者,如果进程在本地别名下注册,您可以使用 Process.whereis/1 进行轮询。直到你得到一个非零值,此时你知道该进程再次运行。

关于elixir - Elixir 中测试主管的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31713791/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com