Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

関数定義を Mix.env に応じて分ける方法とテスト

More than 1 year has passed since last update.

開発時とデプロイ時で関数の定義を変えたいときがある。以下のように書けば、Mix.env の値に応じて、異なる関数がコンパイルされる。

defmodule MyModule do
  @moduledoc false

  if Mix.env() == :prod do
    @foo Application.fetch_env!(:myapp, :foo)
    def foo, do: @foo
  else
    def foo, do: Application.fetch_env!(:myapp, :foo)
  end
end

リリース時に Mix モジュールは存在しないが、この場合、コンパイル時に使われるだけなので問題ない。ただ、このままだとテスト時には片方の実装しかテストされないので、両方をテストしておきたいところ。以下のようにした。

defmodule MyModuleTest do
  use ExUnit.Case

  import ExUnit.CaptureIO

  @source_filepath __DIR__
                   |> Path.join("../../lib/myapp/my_module.ex")
                   |> Path.expand()
  test "foo" do
    on_exit(fn ->
      Mix.env(:test)
    end)

    # suppress warnings
    capture_io(:stderr, fn ->
      Mix.env(:prod)
      Code.compile_file(@source_filepath)
      assert MyModule.foo(), "compile on Mix.env(:prod)"

      Mix.env(:test)
      Code.compile_file(@source_filepath)
      assert MyModule.foo(), "compile on Mix.env(:test)"
    end)
  end
end

Mix.env を変更してから Code.compile_file/2 で対象ファイルを再コンパイルしてやる。on_exit/2 で戻してやるのも忘れずに。

ishikawa@github
Developer in Tokyo ❤️Elixir
https://metareal.blog/
abeja
「ディープラーニング」を活用し、多様な業界、シーンにおけるビジネスの効率化・自動化を促進するベンチャー企業です。
https://abejainc.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away