diff --git a/test/support/case.ex b/test/support/case.ex new file mode 100644 index 0000000..06d1e38 --- /dev/null +++ b/test/support/case.ex @@ -0,0 +1,9 @@ +defmodule BoomNotifier.Case do + @moduledoc false + + use ExUnit.CaseTemplate + + setup do + BoomNotifier.TestMessageProxy.subscribe(self()) + end +end diff --git a/test/support/test_message_proxy.ex b/test/support/test_message_proxy.ex new file mode 100644 index 0000000..5ad4460 --- /dev/null +++ b/test/support/test_message_proxy.ex @@ -0,0 +1,59 @@ +defmodule BoomNotifier.TestMessageProxy do + @moduledoc """ + A gen server that forwards messages to subscribed pids. + Usefull to send responses to test example processes. + + Example: + + use BoomNotifier.Case + + test "receive a message from elsewhere" do + spawn_link(fn -> send(Process.whereis(BoomNotifier.TestMessageProxy), :message) end) + + assert_receive(:message) + end + """ + use GenServer + + def subscribe(pid) do + GenServer.call(__MODULE__, {:subscribe, pid}, 100) + end + + def start_link(opts \\ []) do + GenServer.start_link(__MODULE__, opts, name: __MODULE__) + end + + def stop(reason \\ :shutdown) do + GenServer.stop(__MODULE__, reason) + end + + @impl true + def init(_) do + {:ok, []} + end + + @impl true + def handle_call({:subscribe, pid}, _from, state) do + Process.monitor(pid) + + {:reply, :ok, [pid | state] |> Enum.uniq()} + end + + @impl true + def handle_info({:DOWN, _ref, :process, pid, _reason}, state) do + {:noreply, Enum.reject(state, &(&1 == pid))} + end + + def handle_info(message, state) do + broadcast(message, state) + + {:noreply, state} + end + + defp broadcast(_message, []), do: nil + + defp broadcast(message, [pid | rest]) do + send(pid, message) + broadcast(message, rest) + end +end diff --git a/test/unit/test_helper.exs b/test/unit/test_helper.exs index 071f140..2ef0ac7 100644 --- a/test/unit/test_helper.exs +++ b/test/unit/test_helper.exs @@ -1,2 +1,3 @@ ExUnit.start() +BoomNotifier.TestMessageProxy.start_link() Application.ensure_all_started(:bypass) diff --git a/test/unit/use_test.exs b/test/unit/use_test.exs index 2568bb8..1f508e6 100644 --- a/test/unit/use_test.exs +++ b/test/unit/use_test.exs @@ -1,11 +1,11 @@ defmodule BoomNotifier.UseTest do - use ExUnit.Case + use BoomNotifier.Case @already_sent {:plug_conn, :sent} defmodule Notifier do def notify(%{name: name}, _) do - pid = Process.whereis(BoomNotifier.UseTest) + pid = Process.whereis(BoomNotifier.TestMessageProxy) send(pid, {:notification_sent, name}) end end @@ -15,8 +15,6 @@ defmodule BoomNotifier.UseTest do end setup do - Process.register(self(), BoomNotifier.UseTest) - %{conn: Plug.Test.conn(:get, "/") |> Map.put(:owner, self())} end