Как протестировать функцию, использующую функцию клиентского API, импортированную из другого модуля?

Я пытался найти способ протестировать следующий фрагмент кода (в Эликсире):

 defmacro __using__(_) do 
      quote do
        # API functions will be used from this client
        import Client.API 

        def list_storages do
          case list_buckets do
            {:ok, res} ->
              case res.status_code do
                200 ->
                  res.body
                  |> Friendly.find("name")
                  |> Enum.map(fn bucket -> bucket.text end)
                _   ->
                  res |> show_error_message_and_code
              end
            {:error, reason} ->
              parse_http_error reason
          end
        end
  ...

Проблема в том, что функция list_buckets импортируется из модуля Client.API (это уже тестируется в другом проекте, в котором я ничего не могу там изменить). Моя идея состояла в том, чтобы заглушить/изобразить/заглушить функции API, чтобы они возвращали только фиктивный ответ. Я пытался использовать defoverridable для переопределения функции list_buckets, но это не работает, так как определение функции происходит в другом модуле.

Я прочитал следующий сообщение Хосе Валима. и это помогло протестировать модуль Client.API, но я не нашел способа применить эти концепции к этой конкретной проблеме.

Моя единственная (и глупая) идея на данный момент состоит в том, чтобы просто переопределить каждую функцию внутри макроса в тестовом файле и использовать фиктивную функцию API, определенную там, но это кажется очень неправильным и бесполезным, если есть изменения кода в не тестируемом коде.

В основном я хочу проверить правильность трех возможных случаев:

  1. Получение {:ok, res} и кода 200 -> Выводит правильные данные
  2. Получение {:ok, res} и другого кода -> Вывод сообщения об ошибке и кода
  3. Получение {:error, reason} -> анализирует ошибку HTTP и выводит причину сбоя

Кто-нибудь может мне с этим помочь?


person Sasha Fonseca    schedule 07.05.2016    source источник


Ответы (1)


Вы все еще можете использовать принципы из этого поста в блоге. Вместо импорта Client.Api передайте его как последнюю переменную в list_storages.

def list_storages(api \\ Client.Api) do
  case api.list_buckets do

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

person tkowal    schedule 12.05.2016