在 Elixir 中为动态主管添加 child

Add a child to a Dynamic Supervisor in Elixir

我正在尝试创建一个 DynamicSupervisor 来根据要求监督另一个 GenServer,然后尝试对其进行测试。

这是我的 NodeDynamicSupervisor 代码:

defmodule NodeDynamicSupervisor do
  use DynamicSupervisor

  def start_link() do
    DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
  end

  def init(:ok) do
    DynamicSupervisor.init(strategy: :one_for_one)
  end

  def add_node(private_key, public_key, address, num_of_coins) do
    child_spec = {Node, {private_key, public_key, address, num_of_coins}}
    DynamicSupervisor.start_child(__MODULE__, child_spec)
  end
end

我是这样测试的:

defmodule NodeCreationTest do
  use ExUnit.Case
  import ExUnit.CaptureIO

  test "should create node" do
    {:ok, node_pid} = NodeDynamicSupervisor.start_link()
    capture_io(node_pid.add_node(private_key, public_key, address, 0))
  end 
end

这是我得到的错误:

 code: capture_io(node_pid.add_node(private_key, public_key, address, 0))
 stacktrace:
   :erlang.apply(#PID<0.163.0>, :add_node, [])
   test/create_nodes_test.exs:12: (test)

为什么我无法添加节点并出现此错误?

您的代码有两个问题:


1。您不能在 pid:

上调用方法

您在测试中调用了 node_pid.add_node(...),这是不正确的,而您应该从模块中调用该函数。由于您的 DynamicSupervisor 进程被命名为 (name: __MODULE__) 并且您的 add_node/4 已经在实现中传递了进程 pid/name ,您可以直接调用它:

NodeDynamicSupervisor.add_node(private_key, public_key, address, 0)

2。 capture_io 接受一个函数作为参数:

在您的情况下,您首先调用函数并将其结果传递给方法。您需要在匿名函数中调用该方法并将其传递给 capture_io/1 而不是:

capture_io(fn ->
  NodeDynamicSupervisor.add_node(private_key, public_key, address, 0)
end)