在 Elixir ExUnit 中,我如何保证 Supervisor 会创建一个新的 GeNserver?
In Elixir ExUnit, how do I guarantee that the Supervisor will create a new GeNserver?
我正在学习在 Elixir 中进行测试,出现了这个问题:
当我运行以下测试时,有时它通过有时不通过,我认为这是Supervisor没有时间重新启动GenServer的事实:
test "Supervisor will revive the dead gensever" do
{:ok, pid} = KV.Supervisor.start_link([])
KV.RegistryClient.create KV.RegistryClient, "wallet"
[h | _] = Supervisor.which_children(pid)
{KV.RegistryClient, pid_reg, _, _} = h
send(pid_reg, :insta_kill)
assert %{active: 1} = Supervisor.count_children(pid)
end
发生时,这是错误:
1) test Supervisor will revive the dead gensever (KV.RegistryTest)
test/kv/registry_test.exs:35
match (=) failed
code: assert %{active: 1} = Supervisor.count_children(pid)
right: %{active: 0, specs: 1, supervisors: 0, workers: 1}
stacktrace:
test/kv/registry_test.exs:41: (test)
如何防止这种情况发生?超时是一个好方法吗?
这是时间问题。简短的版本是不要费心测试 OTP。 IT 已经经过很好的测试。
但如果您将来遇到需要确保启动正常工作的情况,了解 Supervisors 如何启动服务器很有用,请观看此视频
https://www.youtube.com/watch?v=2i_XrY5CCXE
在没有竞争条件的情况下有效测试此行为的唯一方法是:
确保旧进程已死。这可以通过在发送 kill 信号之前监视进程然后 assert_receive {:DOWN, ^monitor_ref, _, _, _}
来完成
查询supervisor,直到活跃计数变为1。这可以通过每 10 毫秒左右执行一次函数来完成
但是,正如其他人所说,Erlang/OTP 保证了这种行为。因此,我宁愿测试您是否将正确的子规范传递给主管,而不是测试主管是否真的重新启动了某些东西。所以假设主管开始一个基于 KV.Registered
的处理,我会这样做:
assert %{restart: :permanent} = Supervisor.child_spec(KV.Registered)
换句话说,我会与监管者一起测试合同,而不是监管者自己测试。
我正在学习在 Elixir 中进行测试,出现了这个问题:
当我运行以下测试时,有时它通过有时不通过,我认为这是Supervisor没有时间重新启动GenServer的事实:
test "Supervisor will revive the dead gensever" do
{:ok, pid} = KV.Supervisor.start_link([])
KV.RegistryClient.create KV.RegistryClient, "wallet"
[h | _] = Supervisor.which_children(pid)
{KV.RegistryClient, pid_reg, _, _} = h
send(pid_reg, :insta_kill)
assert %{active: 1} = Supervisor.count_children(pid)
end
发生时,这是错误:
1) test Supervisor will revive the dead gensever (KV.RegistryTest)
test/kv/registry_test.exs:35
match (=) failed
code: assert %{active: 1} = Supervisor.count_children(pid)
right: %{active: 0, specs: 1, supervisors: 0, workers: 1}
stacktrace:
test/kv/registry_test.exs:41: (test)
如何防止这种情况发生?超时是一个好方法吗?
这是时间问题。简短的版本是不要费心测试 OTP。 IT 已经经过很好的测试。
但如果您将来遇到需要确保启动正常工作的情况,了解 Supervisors 如何启动服务器很有用,请观看此视频 https://www.youtube.com/watch?v=2i_XrY5CCXE
在没有竞争条件的情况下有效测试此行为的唯一方法是:
确保旧进程已死。这可以通过在发送 kill 信号之前监视进程然后
assert_receive {:DOWN, ^monitor_ref, _, _, _}
来完成
查询supervisor,直到活跃计数变为1。这可以通过每 10 毫秒左右执行一次函数来完成
但是,正如其他人所说,Erlang/OTP 保证了这种行为。因此,我宁愿测试您是否将正确的子规范传递给主管,而不是测试主管是否真的重新启动了某些东西。所以假设主管开始一个基于 KV.Registered
的处理,我会这样做:
assert %{restart: :permanent} = Supervisor.child_spec(KV.Registered)
换句话说,我会与监管者一起测试合同,而不是监管者自己测试。