2014-01-06 3 views
41

Функции, заданные defp, не экспортируются, поэтому я не могу выполнить их в местах, отличных от модуля.Есть ли способ проверить частные функции в модулях ExUnit Elixir?

+3

Интересно, если можно было бы написать макрос, который расширяется в 'defp' в DEV и PROD Смешать среды, и' def' в тестовой среде? – TalkLittle

+0

@TalkLittle Да, это возможно. См. Мой ответ ниже. – acj

ответ

66

Нет, нет возможности протестировать их через ExUnit.

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

+21

FYI, это хороший совет, независимо от языка или библиотеки тестирования. –

+0

Я не согласен с уважением: Есть два способа проверить. На a beha – lab419

+6

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

9

В определении вашего модуля вы можете указать директиву @compile для экспорта ваших личных функций только в тестовую среду.

defmodule Foo do 
    @compile if Mix.env == :test, do: :export_all 

    # This will be exported for tests 
    defp bar() do 
    ... code ... 
    end 
end 
+1

Обновление: это выдает предупреждение в Elixir 1.5, поэтому это может быть не самый лучший способ. –

1

Можно изменить видимость функции в зависимости от окружающей среды с помощью макроса:

defmacro defp_testable(head, body \\ nil) do 
    if Mix.env == :test do 
    quote do 
     def unquote(head) do 
     unquote(body[:do]) 
     end 
    end 
    else 
    quote do 
     defp unquote(head) do 
     unquote(body[:do]) 
     end 
    end 
    end 
end 

Затем вы можете выставить функции для ваших тестов следующим образом:

defp_testable myfunc do 
    ... 
end 

I рекомендуем использовать это с осторожностью по причинам, указанным в ответе Жозе. Это не заменяет проверку внешнего поведения модуля. Однако это может быть полезно в определенных сценариях.

(Source)

+0

Уход! Это работает, когда 'myfunc' принимает аргументы? – TalkLittle

+0

@TalkLittle Действительно. Макрос влияет только на видимость и оставляет параметры/тело неизменным. – acj

Смежные вопросы