In our ExUnit tests we initiate a process via delivering a message "at a distance" and don't receive a pid. When the app processes the message it spawns an ephemeral "manager" process that executes a series of tasks, the output of which we test for. We're currently using the venerable Process.sleep() in the hope the output is ready by then, which is not ideal.
It looks like a Registry is appropriate to keep track of dynamic running processes so I modified the init in our GenServer to register itself:
def init(arg) do
Registry.register(App.RunningManagers, :running, true)
{:ok, arg}
end
This works in the test as below, because the test process can now Process.monitor() the running process and receive notification when it ends. But I still need a sleep() before because the process to monitor might not have started yet.
test "outputs a file" do
trigger_message()
Process.sleep(1000) # I want to get rid of this
[{pid, _}] = Registry.lookup(App.RunningManagers, :running)
Process.monitor(pid)
receive do
{:DOWN, _, :process, _, _} -> nil
end
assert file_is_there()
end
Is there a way to nicely wait for it to start? I'm aware that Registry.start_link can take a listeners option, but it requires a named process and I don't want to pollute my production supervision tree with the concerns of tests.