ExUnit - Как передать контекст для тестовых макросов в блоках описания с помощью именованных функций настройки

Глядя на документацию ExUnit, вы можете добавить свойства в структуру context по следующему шаблону:

defmodule KVTest do
  use ExUnit.Case

  setup do
    {:ok, pid} = KV.start_link
    {:ok, pid: pid}
    # "[pid: pid]" also appears to work...
  end

  test "stores key-value pairs", context do
    assert KV.put(context[:pid], :hello, :world) == :ok
    assert KV.get(context[:pid], :hello) == :world

    # "context.pid" also appears to work...
  end
end

Но при использовании макроблоков describe рекомендуется использовать следующую форму для предоставления функций настройки для ваших тестов:

defmodule UserManagementTest do
  use ExUnit.Case, async: true

  describe "when user is logged in and is an admin" do
    setup [:log_user_in, :set_type_to_admin]

    test ...
  end

  describe "when user is logged in and is a manager" do
    setup [:log_user_in, :set_type_to_manager]

    test ...
  end

  defp log_user_in(context) do
    # ...
  end
end

Это работает хорошо, но нет упоминания о том, как добавить новые свойства в структуру контекста для использования в тестах при использовании макроса describe и именованных настроек.

До сих пор я пробовал (краткое резюме):

  ...
  describe "when user is logged in and is a manager" do
    setup [:test]

    test(context) do
       IO.puts("#{ inspect context }") # Comes up as 'nil'
    end
  end

  defp test(context) do
    [test: "HALLO"]
  end
  ...

Можно ли таким образом манипулировать контекстом набора тестов при создании функций настройки для блоков описания?


person Charlie    schedule 05.09.2018    source источник
comment
Значит, простое возвращение карты или списка ключевых слов из log_user_in не работает для вас? Ваша попытка также содержит синтаксическую ошибку.   -  person Dogbert    schedule 05.09.2018
comment
Ошибка? setup [:test] ты имеешь в виду? Вполне могут быть и другие... Но да, пока пробовал с { test: "HALLO" }, [ test: "HALLO" ] и %{ test: "HALLO"}. Можно использовать обычный макрос setup.   -  person Charlie    schedule 05.09.2018
comment
Tbh Dogbert, выявив синтаксическую ошибку в примере, который я предоставил, я вернулся к фактическому коду и выбрал свою ошибку. Приму ответ ниже, несмотря на этот факт, так как он правильный.   -  person Charlie    schedule 05.09.2018


Ответы (1)


Вы делаете часть настройки правильно. Названные функции установки принимают контекст в качестве параметра, и их возвращаемые значения автоматически объединяются с контекстом. Таким образом, у вас уже есть ключ :test для ваших тестов.

Вам просто нужно получить контекст в ваших тестах в качестве второго аргумента, например:

describe "when user is logged in and is a manager" do
  setup [:test]

  test "does the right thing", context do
     IO.inspect(context) # Will not come up as nil
  end
end

Но, что более интересно, вы можете использовать сопоставление с образцом, чтобы получить именно те ключи, которые вам нужны, из контекста:

describe "when user is logged in and is a manager" do
  setup [:test]

  test "does the right thing", %{test: test} do
     IO.inspect(test) # "HALLO"
  end
end
person Marcelo De Polli    schedule 05.09.2018
comment
Это правильно, но это исключительно запутанно, потому что в вопросе используется одно и то же имя для частной функции и ключа контекста. - person Steve; 04.04.2021