Вернуть фиктивный модуль к исходному - PullRequest
0 голосов
/ 20 июня 2020

Я работаю с эликсиром и вижу непонятное / нежелательное поведение при использовании Mox.

Я просто хочу использовать макет для одного тестового модуля. Допустим, у меня есть 2 теста. Вот пример кода:

defmodule MyTest do
  setup_all do
    defmock(DateTimeMock, for: DateTimeApi)

    :ok
  end

  test "test1" do
    {:ok, expected_datetime, _} = DateTime.from_iso8601("2019-09-08T00:00:00.000000Z")
    expect(DateTimeMock, :utc_now, fn _ -> expected_datetime end)
  end

  test "test2" do
    expect(something else)
  end
end 

defmodule MyTest2 do
  setup_all do
    defmock(DateTimeMock, for: DateTimeApi)

    :ok
  end

  test "test1" do
  end

  test "test2" do
  end
end 

Когда MyTest2 запустится, я увижу ошибку: (Mox.UnexpectedCallError) ожидание не определено

Определение макета для одного теста 'просачивается' и влияет все тесты.

Есть ли у Mox способ вернуть фиктивный модуль обратно к исходному модулю после завершения теста?

1 Ответ

0 голосов
/ 22 июня 2020

Вы можете использовать обратный вызов on_exit в блоке setup. Основная часть функции настройки запускается перед каждым тестом (таким образом, он считывает текущее значение), затем обратный вызов on_exit запускается после каждого теста (так что он может вернуть все обратно в их исходные значения).

defmodule MyTest do
  use ExUnit.Case

  setup do
    date_time_api = Application.get_env(:my_app, :date_time_api)
    on_exit(
      fn ->
        Application.put_env(:my_app, :date_time_api, date_time_api)
      end
    )
  end

  # Tests, fixtures follow...
end

Помните, что важно, чтобы ваш код подчинялся конфигурации времени выполнения, доступной в Приложении, поэтому ваш код может выглядеть примерно так:

def utc_now do
  Application.get_env(:my_app, :date_time_api).utc_now()
end

С соответствующим значением конфигурации, например,

# config/config.exs or env-specific config file
config :my_app, date_time_api: DateTimeApi

Это то, что заставляет все это работать, потому что приложение будет разрешать имя модуля (то есть реальное или фиктивное) во время выполнения.

...