While executing ExUnit.start
, in each case, I prepare mocks by meck
like bellow
defmodule MyModule.FooTest do
use ExUnit.Case, async: false # explicitly sync
import :meck
alias MyModule.Foo
alias MyModule.Baz # to be mocked
test "call_baz" do
expect(Baz, :some_async_method, [
{[], :meck.val(Task.async(fn -> %{"name" => "otiai10"} end)},
])
assert Foo.call_baz() == %{"name" => "otiai10"}
end
end
But it returns {"name" => "otiai200"}
, because Baz.some_async_method
is mocked by another test with returning {"name" => "otiai200"}
.
It is certainly the response of what mocked in another test cases. (They are also given async: false
option in their use
statement)
What is the problem, async: false
option doesn't work? or is mocking Task.async
not recommended? Or do I do any basic mistakes?
Thank you
Meck requires explicit unloading of mocks. Therefore, it is possible that another test running in parallel will update the expectation while you are running this test. Try adding
:meck.unload(Baz)
in the teardown to each test using the mock.I'm not familiar with how Elixir decides to run it's test suites (maybe in parallel, even though they are async internally?) so this might factor in. As Meck is modifying the global module namespace, you should not mock the same module in parallel from different test cases.
I'd suggest trying to use the Meck wrapper Mock for Elixir to see if this gives you the same result.