I’ve defined a GenServer
like this:
def MyModule do
use GenServer
def start_link(opts) do
GenServer.start_link(__MODULE__, opts)
end
def init(opts) do
{submodule, opts} = Keyword.pop!(opts, :submodule)
{:ok, pid} = submodule.start_link(opts)
{:ok, %{submodule: pid}
end
end
submodule
is another Elixir module with a different set of responsibilities, passed as an option. It includes a behaviour definition something like this:
defmodule MySubmodule do
@callback start_link(any()) :: {:ok, pid()} | {:error, term()}
end
Then the mock is defined as you might expect like this:
Mox.defmock(MySubmoduleMock,
for: MySubmodule
)
My tests look a bit like this so far:
defmodule MyModuleTest do
use ExUnit.Case, async: true
import Mox
setup do
SubmoduleMock
|> expect(:start_link, fn opts ->
{:ok, "fake-pid"}
end)
client = start_supervised!({Client, connection: SubmoduleMock})
{:ok, %{ client: client }}
end
test "etc etc", %{ client: client } do
assert client
end
end
When I attempt to run the test I get Mox.UnexpectedCallError
. The calling process in this case is an instance of MyModule
.
I can work around this by enabling global mode. But then that means I have to get rid of async: true
and I’d prefer not to if possible.
Since MyModule
hasn’t been started, I don’t have a pid
to call Mox.allow/3
with.
Is there a way of achieving this without resorting to Mox global mode? Perhaps I’ve arranged my process hierarchy in a mad way… so I’m open to suggestions to modify that too.
Thanks as always for help!