在 Elixir Supervisor 和 Application 教程中,为什么 assert_receive 超时?

In the Elixir Supervisor and Application tutorial, why does the assert_receive time out?

在 Elixir 入门教程中,在关于 Supervisors and Applications 的页面上,有一个名为 "removes bucket on crash" 的测试。在页面上添加代码后(我想我添加了它,可能遗漏了一些东西),测试失败并在 assert_receive.

中超时
test "removes bucket on crash", %{registry: registry} do
    KV.Registry.create(registry, "shopping")
    {:ok, bucket} = KV.Registry.lookup(registry, "shopping")

    # Kill the bucket and wait for the notification
    Process.exit(bucket, :shutdown)
    assert_receive {:exit, "shopping", ^bucket}
    assert KV.Registry.lookup(registry, "shopping") == :error
end

这是输出:

$ mix test
....

1) test removes bucket on crash (KV.RegistryTest)
   test/kv/registry_test.exs:49
   No message matching {:exit, "shopping", ^bucket} after 100ms. Process mailbox:
   {:create, "shopping", #PID<0.137.0>}
   stacktrace:
     test/kv/registry_test.exs:55

Process.exit 的帮助说,如果进程被困退出,消息将是 {:EXIT, from, reason}。

跟踪此类错误的好策略是什么?

我认为您的实施存在问题 in this line 您等待带有退出原因 :normal:DOWN 消息。如果存储桶进程因任何其他原因终止,您将不会匹配此消息,并且不会传播到 GenEvent.

:normal 更改为 _(以匹配进程退出的任何原因)修复了测试。

我的做法是,在理解了代码并且没有发现明显的错误之后,我添加了一些临时文件。 IO.inspect 在一些地方。我立即注意到注册表进程不处理 :DOWN 消息。看到监视器设置正确,我怀疑消息的模式匹配方式一定有问题。盯着那条线几秒钟给了我答案:-)