在Elixir入门教程中,在关于Supervisors and Applications的页面上,有一个名为“在崩溃时移除存储桶”的测试。在页面上添加代码后(我想我添加了它,可能会遗漏一些东西),测试失败并在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}。
跟踪这样的错误有什么好的策略?
答案 0 :(得分:1)
我认为您的实施问题是in this line
您等待:DOWN
消息,退出原因为:normal
。如果存储区进程因任何其他原因而终止,则您将无法匹配此消息,并且它不会传播到GenEvent
。
将:normal
更改为_
(以匹配流程退出的任何原因)修复了测试。
我得出的方法是,在理解了代码并且没有看到明显的错误之后,我添加了一些临时值。 IO.inspect
在几个地方。我立即注意到注册表进程没有处理:DOWN
消息。看到显示器设置正确,我怀疑消息的模式匹配方式有问题。盯着那条线几秒钟给了我答案: - )