erlang 如何测试消息是否已发送到GenServer进程

wkyowqbh  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(165)

我将GenServer作为后台作业运行,每个interval都会重新调度。
此作业由主管在应用程序启动时启动。
它工作得很好,但是现在我想测试一下我的GenServer模块是否真的在每个interval生成新进程。
如何测试?

  • 编辑 *

我发现可以使用:sys.get_status(pid)来获取一些关于进程数据,但我确实希望使用类似receive do ... end的数据,

编辑2

handle_info/2函数:

@impl true
def handle_info(:work, state) do
  do_smt()

  schedule_worker()

  {:noreply, state}
end

schedule_worker/0函数:

defp schedule_worker do
  Process.send_after(self(), :work, @interval)
end
wgeznvg7

wgeznvg71#

您的消息中缺少某些内容。从您发布的内容中,我们可以了解到每隔@interval毫秒就会发送一条:work消息。您没有告诉我们在发送消息时handle_info/2应该执行什么操作。
一旦定义了它,就可以使用assert_receivedAssert编写一个测试来Assert消息已经收到。

w6lpcovy

w6lpcovy2#

I would test do_smt() by using Mock library and writing a test that makes as assertion like the following:

with_mock(MyModule, [do_stm_else: fn -> :ok]) do
   do_smt()

   assert_called MyModule.do_stm_else()
end

In this way, you have called the function that the task should execute, so you can assume that the task creation is being called.
If you want to let the do_stm_else function communicate with your test (in this scenario it looks a bit overengineered) you should:

  1. get the pid of the test by calling self()
  2. Pass the pid to the mock function to get it used
  3. use assert_receive to verify that the communication has occurred
pid = self()

with_mock(MyModule, [do_stm_else: fn -> 
      Process.send(pid, :msg)
   ]) do
   do_smt()

   assert_called MyModule.do_stm_else()
end

assert_receive(:msg)

Please note that I had no time to check this, you should spend a bit to investigate.

相关问题