4

我有两个模块:

defmodule Base.ModuleOne do
  def do_stuff(opts) do
    "some stuff with opts"
  end
end

defmodule Base.ModuleTwo do
  defdelegate do_stuff(opts), to: Base.ModuleOne
end

什么是测试委派的正确方法,而无需复制粘贴测试Base.ModuleOne.do_stuff/1不同命名空间下的功能?

4

1 回答 1

2

在撰写此答案时,我还没有找到一种“官方”的测试defdelegate方式。在您的情况下,我能想到的唯一选择是:

  1. Base.ModuleTwo.do_stuff(opts)只需忽略Base.ModuleOne.do_stuff(opts).
  2. 将大部分(如果不是全部)测试Base.ModuleOne.do_stuff(opts)移到测试中,Base.ModuleTwo.do_stuff(opts)以便您的测试直接与模块的公共接口相关,Base.ModuleOne从而成为“私有”实现细节。
  3. 由于在 Elixir 中模拟似乎通常不受欢迎,请考虑用defdelegate依赖注入替换(使用函数或模块;有关详细信息,请参阅上一个链接),这样您就可以通过以下方式编写测试:

模块:

defmodule Base.ModuleTwo do
  def do_stuff(opts, dependency \\ Base.ModuleOne)
    dependency.do_stuff(opts)
  end
end

测试:

defmodule ModuleTwoTest do
  use ExUnit.Case

  describe "Base.ModuleTwo.do_stuff/2" do
    defmodule TestDependency do
      def do_stuff(_opts) do
        send self(), :do_stuff
      end
    end

    test "calls do_stuff/1 on its dependency" do
      opts = %{foo: "bar"} # or whatever the `opts` should be
      Base.ModuleTwo.do_stuff(opts, TestDependency)
      assert_received :do_stuff
    end
  end
end
于 2017-07-09T04:40:11.363 回答