Делегирование методов тестирования в Elixir

У меня есть два модуля:

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 в другом пространстве имен?


person kovpack    schedule 22.07.2016    source источник


Ответы (1)


На момент написания этого ответа я также не нашел «официального» способа проверить 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. Поскольку насмешки в Эликсире обычно не в моде, рассмотрите возможность замены 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
person Paul Fioravanti    schedule 09.07.2017