I'm using Mox to mock a service Pokemon.Api
(mock is called Pokemon.ApiMock
) and everythings works fine. I have also created a custome ExUnit.CaseTemplate(Pokemon.Case
) and am stubbing the mock implementation with the real implementation. So if I havent defined a mox.expect the test till relay on the real implementation (Pokemon.Api
). This also works fine.
However here is when the problem comes ...
I also have a DynamicSupervisor
which initiated a Genserver
, and that genserver will use Pokemon.Api
(or Pokemon.ApiMock
in some testcases).
In the testcases where I have defined a mox.expect the test works as usual. However if I haven't defined an expect, and should relay and the stub(real impentation) the test crashes. (And remember this doesn't happen if I try to access the implementation throgh the service.
Exception
** (Mox.VerificationError) error while verifying mocks for #PID<0.223.0>:
* expected Pokemon.ApiMock.get_by_id/1 to be invoked once but it was invoked 0 times
stacktrace:
(mox 1.0.1) lib/mox.ex:713: Mox.verify_mock_or_all!/3
(ex_unit 1.13.0) lib/ex_unit/on_exit_handler.ex:143: ExUnit.OnExitHandler.exec_callback/1
(ex_unit 1.13.0) lib/ex_unit/on_exit_handler.ex:129: ExUnit.OnExitHandler.on_exit_runner_loop/0
Genserver
defmodule Pokemon.Server do
....
@impl true
def handle_info(:get, state) do
# bit weird, but only for demonstration purposes :)
_ = api_imp().get_by_id(1)
{:noreply, state}
end
def api_imp() do
Application.get_env(:pokemon, :api)
end
end
Case
defmodule Pokemon.Case do
use ExUnit.CaseTemplate
setup _ do
Mox.stub_with(Pokemon.ApiMock, Pokemon.Api)
:ok
end
end
test_helper
Mox.defmock(Pokemon.ApiMock, for: Pokemon.ApiBehavoir)
Application.put_env(:pokemon, :api, Pokemon.ApiMock)
ExUnit.start()
tests Test 1 works but test 2 crashes...
defmodule PokemonTest do
use Pokemon.Case
import Mox
setup :set_mox_from_context
setup :verify_on_exit!
test "1" do
Pokemon.Supervisor.get(1)
.....
end
test "2" do
expect(Pokemon.ApiMock, :get_by_id, fn _ -> {:ok, "fake"} end)
Pokemon.Supervisor.get(1)
....
end
end
Not really sure how I should proceed and would appriciate any help I can get If I have been unclear at any point please tell
Thanks!