我有一个GenServer执行定期操作,如下所示:
defmodule Hello
use GenServer
def init(_) do
Process.send_after(self(), :timer, 1000)
{:ok, %{}}
end
def handle_info(:timer, state) do
# do stuff
Process.send_after(self(), :timer, 1000)
{:noreply, state}
end
end
我试图找出对其进行单元测试的最佳方法。我最初的想法是使用mox来存根Process.send_after。这工作正常,但在我的单元测试中,我尝试过这样的事情:
test "the timer callback does the right thing" do
MyMock |> expect(:timer, fn -> :ok end)
{:ok, pid} = start_supervised(Hello, [])
Process.send(pid, :timer)
# assert the right thing happens
end
但是,这不起作用,因为Process.send
是异步的,并且不会给我任何回报。我还能如何测试handle_info
回调?
答案 0 :(得分:0)
有许多选项,例如可能会从setup_all
回调中生成Agent
并在模拟和断言中使用它:
expect(MyMock, :timer, fn -> Agent.update(MyAgent, & &1 + 1))
...
Process.sleep(1_100) # ensure all sent
assert Agent.get(MyAgent, & &1) == 1 # number of calls
最简单的方法是捕获IO:
import ExUnit.CaptureLog
...
test "the timer callback does the right thing" do
MyMock |> expect(:timer, fn -> IO.inspect(:ok) end)
{:ok, pid} = start_supervised(Hello, [])
assert capture_log(fn ->
Process.send(pid, :timer)
Process.sleep(1_100)
end) =~ "ok"
end