Not working, at least not in the way I expected
naps62 opened this issue · comments
I'm finding that this package does not work when mocking functions that are called indirectly. Here's the example I came up with to reproduce:
defmodule MyApp.MyMod do
def value do
1
end
def indirect_value do
value()
end
end
and here are some assertions I tried to make for it:
defmodule MyApp.MyModTest do
use ExUnit.Case, async: false
import Mock
alias MyApp.MyMod
test "test" do
# these two work, obviously
assert MyMod.value == 1
assert MyMod.indirect_value == 1
# in this block, the second assertion fails with:
# (UndefinedFunctionError) function MyApp.MyMod.indirect_value/0 is undefined (module MyApp.MyMod is not available)
# I guess this is to be expected, although unintuitive
with_mock MyMod, [value: fn -> 2 end] do
assert MyMod.value == 2
assert MyMod.indirect_value == 2
end
# and in this block (adding :passthrough), the second assertion fails, because the indirect_value function still returns 1
with_mock MyMod, [:passthrough], [value: fn -> 2 end] do
assert MyMod.value == 2
assert MyMod.indirect_value == 2
end
end
end
I'm not sure how I should use the package to test this kind of calls, if that's at all possible
What you're describing is definitely not the behavior I'd expect either. Unfortunately, I don't have a good solution to this right now...
According to http://elixir-lang.readthedocs.io/en/latest/technical/scoping.html:
Any unbound identifier is treated as a local function call
When we're using the :passthrough
flag and call indirect_value
, we enter the scope of MyMod
and execute the locally scope function since we're not referencing it via the module name. The only workarounds I have to this at the moment are:
- Replacing
value()
with__MODULE__.value()
- Mocking
indirect_value
in your test - Using dependency injection and passing:
Implementation would look like this:
def indirect_value(value) do
value.()
end
Test will look like this:
assert MyMod.indirect_value(&MyMod.value/0) == 2
All of this being said, I'm going to keep thinking about this for a little while longer to see if we could get the expected behavior to function properly.
I'm having the same exact problem! Would love to see a solution.
same issue here
I've been looking for a solution for this on and off.
The only potential path I've found so far is manually updating the beam file after compilation. There are still a couple hooks I need to jump through to get it working but I'll keep this thread updated.
+1
+1
+1