Monitor Tasks in test

Hi!

I have a function that runs some code in a separate Task, under a TaskSupervisor.

def send_to_devices(endpoints, message) do
  for endpoint_arn <- endpoints do
    Task.Supervisor.start_child(MyApp.TaskSupervisor, fn ->
      IO.inspect("foo")
    end)
  end
end

Then, in my test, I want to test this somehow. I’ve tried this:

tasks = Foo.send_to_devices(["endpoint-1", "endpoint-2", "endpoint-3"], "some-payload")
Enum.each(tasks, fn({:ok, pid})->
  ref = Process.monitor(pid)
  assert_receive {:DOWN, ^ref, :process, _, :normal}, 500
end)

But I can’t get it to work. Some processes returns :normal but others return :noproc.

     No message matching {:DOWN, ^ref, :process, _, :normal} after 500ms.
     The following variables were pinned:
       ref = #Reference<0.0.4.312>
     Process mailbox:
       {:DOWN, #Reference<0.0.4.312>, :process, #PID<0.404.0>, :noproc}

Why is that? What did I miss? :slight_smile:

2 Likes

After some Slack discussion @fishcakez told me that the error happens because the process has already finished when I try to monitor it. I’ll have to rewrite some code here and be back with how I solved it :slight_smile:

5 Likes