jjh42 / mock

Mocking library for Elixir language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Stubbing out methods from use-d code...

twajjo opened this issue · 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.