defp
で定義された関数はエクスポートされないため、モジュール以外の場所では実行できません。
いいえ、ExUnit経由でテストする方法はありません。
私は個人的にプライベート関数のテストを避けています。通常、動作の代わりに実装をテストし、コードを変更する必要があるとすぐにそれらのテストが失敗するためです。代わりに、パブリック関数を介して予想される動作をテストし、小さくて一貫したチャンクに分割します。
モジュール定義では、@compile
ディレクティブ-プライベート関数をエクスポートするonlyテスト環境で。
defmodule Foo do
@compile if Mix.env == :test, do: :export_all
# This will be exported for tests
defp bar() do
... code ...
end
end
マクロを使用して、環境に応じて関数の可視性を変更できます。
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
ホセの回答にある理由から、これは控えめに使用することをお勧めします。モジュールの外部動作をテストする代わりにはなりません。ただし、特定のシナリオでは価値があります。
( ソース )
ExUnitを使用したテストのコンテキストであっても、プライベート関数をモジュールの外部から呼び出すことはできません。
テスト用にプライベート関数を公開するための複雑な方法を提案する人もいるので、もっと簡単に見える次の2つを提案します。
1)テストする関数を公開しますが、@doc false
でマークします。つまり、モジュールの公開APIの一部ではありません。
2)あるいは、テストする関数がdefp foo
の場合、同じモジュールでdef test_foo
を作成します。これは、テスト中に変更する引数を受け取り、それらをfoo
は期待し、最後にfoo
を呼び出します。このようなテスト中にのみ、特別なテスト関数を生成することもできます
if Mix.env == :test do
def test_foo ...
end
これらの代替案はいずれも単純で、プロジェクトに追加の依存関係は必要ありません。
もちろん、他の人が述べたように、一般的なルールはプライベート関数のテストを避けることですが、それらをテストすることは、テストを容易にし、テストの範囲を広げる方法です。
良いコーディング!