Stubbing out methods from use-d code...
twajjo opened this issue · 2 comments
I want to stub out a function that is in a module use-d by another module, like so:
defmodule A do
defmacro __using__(_opts) do
quote do
def avoid_during_test(foo) do
{:error, "don't ever want to get here during test"}
end
end
end
end
defmodule B do
use A
def init() do
avoid_during_test(:ignored_in_test_anyway)
exec_during_test(:whatever)
end
end
In the test script:
defmodule BTest do
use ExUnit.Case
import Mock
test "my test" do
with_mocks([
{B, [:passthrough], [avoid_during_test: fn(_arg) -> :ok end]}
]) do
B.init()
assert(true)
end
end
end
Attempting to run mix test
results in the following bundle of joy...
** (ErlangError) Erlang error: {:undefined_function, {B, :avoid_during_test, 1}}
(meck) <path to project>/deps/meck/src/meck.erl:712: :meck.check_expect_result/1
(mock) lib/mock.ex:150: Mock._install_mock/2
(elixir_lib) test/util/b_test.exs:11: anonymous fn/2 in BTest."my test"/1
(elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
test/util/b_test.exs:5: (test)
In iex -S mix
, if I can run B.__info__(:functions)
and, lo and behold, I get:
[
...
avoid_during_test: 1,
exec_during_test: 1,
...
]
This is not the first time I have encountered this problem, but it's the first time I couldn't find a reasonable work-around I am comfortable with. If it is recognized as essentially a function native to B by the module, why is it not recognized as such by Mock? The arity is correct and everything...
In real life, this issue arose when I was attempting to unit test a module (substituted with B in the example) that uses another module (A) to set up an AMQP endpoint (publisher or subscriber) based on a config buffer (the args). I really don't want to stub out the multiple AMQP and Process.monitor calls in that use-d module's (A's) function, when I just want to assume a valid connection is established.
Being a neurotic, I assume I must be doing something wrong, but am willing to accept that this might be a bug in how Mock works.
Erlang version: 19.2
Elixir version: 1.6.5
Mock version: 0.2.0
Thanks for your time and attention.
Jeff Osborn, universal threat to the gene pool.
Crickets?
@twajjo I recommend you try upadting OTP and using the latest mock version. Here are the stats of my machine
Erlang/OTP 20 [erts-9.3.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.6.5) - press Ctrl+C to exit (type h() ENTER for help)
I made a branch with your code and running mix test test/test_module_test.exs
works for me.