2017-04-22 5 views
2

私は私のメインモジュールの定数をこのように定義しています:エリクサーテストで定数を使用するには?

@end_digits_adjusters [11, 12, 14, 21, 22, 23] 

は、ここで私はそれをテストしようとしている方法は次のとおりです。

動作しません
defmodule PriceOptimizerTest do 
    use ExUnit.Case 
    doctest PriceOptimizer 

    test "get_random_adjuster() randomizer" do 
    adj_num = PriceOptimizer.get_random_adjuster() 
    is_in? = adj_num in @end_digits_adjusters 
    assert is_in? == true 

    end 
end 

。しかし、テストで一定値を明示的に指定すると機能します。このように...

is_in? = adj_num in [11, 12, 14, 21, 22, 23] 

私はエリクシールはテストで、モジュールの定数を認識してもらうために、どこかのステップ足りませんか?

答えて

1

恐らく、Elixir's module attributesは定義されているモジュール内でのみ使用できます。これは、コンパイル時にこれらの属性がオンラインでコード化されているためです。

あなたがそれらを公にアクセスようにしたい場合は、例えば、機能でそれをラップする必要があります。

だから、
defmodule MyMod do 
    @test "hello" 

    def test, do: @test 
end 

MyMod.test # => "hello" 

希望に役立ちます!

+0

定数をラップすることなく、定数を使用するテストを構築するためのエレガントな回避策がありますモジュールで? – Emily

+0

@エミリーいいえ、他の方法はありません。 – Doodloo

3

他の言語でもよく使われる共有定数は、Elixirでは一般的なパターンではありません。私は個人的にパターンを使用する必要はほとんどないことを発見しました。しかし、私がリレーに重点的に構築したアプリケーションがあります。

私はそれらを必要行うと、私は、次のモジュールを使用定数モジュールがあります。

defmodule Constants do 
    @moduledoc """ 
    An alternative to use @constant_name value approach to defined reusable 
    constants in elixir. 

    This module offers an approach to define these in a 
    module that can be shared with other modules. They are implemented with 
    macros so they can be used in guards and matches 

    ## Examples: 

    Create a module to define your shared constants 

     defmodule MyConstants do 
     use Constants 

     define something, 10 
     define another,  20 
     end 

    Use the constants 

     defmodule MyModule do 
     require MyConstants 
     alias MyConstants, as: Const 

     def myfunc(item) when item == Const.something, do: Const.something + 5 
     def myfunc(item) when item == Const.another, do: Const.another 
     end 

    """ 

defmacro __using__(_opts) do 
    quote do 
     import Constants 
    end 
    end 

    @doc "Define a constant" 
    defmacro constant(name, value) do 
    quote do 
     defmacro unquote(name), do: unquote(value) 
    end 
    end 

    @doc "Define a constant. An alias for constant" 
    defmacro define(name, value) do 
    quote do 
     constant unquote(name), unquote(value) 
    end 
    end 

    @doc """ 
    Import an hrl file. 

    Create constants for each -define(NAME, value). 
    """ 
    defmacro import_hrl(file_name) do 
    list = parse_file file_name 
    quote bind_quoted: [list: list] do 
     for {name, value} <- list do 
     defmacro unquote(name)(), do: unquote(value) 
     end 
    end 
    end 

    defp parse_file(file_name) do 
    for line <- File.stream!(file_name, [], :line) do 
     parse_line line 
    end 
    |> Enum.filter(&(not is_nil(&1))) 
    end 

    defp parse_line(line) do 
    case Regex.run ~r/-define\((.+),(.+)\)\./, line do 
     nil -> nil 
     [_, name, value] -> 
     {String.strip(name) |> String.downcase |> String.to_atom, String.strip(value) |> parse_value} 
     _ -> nil 
    end 
    end 

    defp parse_value(string) do 
    case Integer.parse string do 
     :error -> filter_string(string) 
     {num, _} -> num 
    end 
    end 

    defp filter_string(string), do: String.replace(string, "\"", "") 
end 

カップルノート:

  • 彼らはパターンマッチングで作業を!
  • 定数モジュールをインポートしないでください。彼らは
  • 別名に簡潔 `エイリアスMyConstantsModためのモジュールを定義している場所を見つけるのは難しい。その、とします。Const
  • また、このモジュールは、ErlangのHRLファイルでrequire文へ
  • 注意を払う作業をサポートしています。 defineはマクロです。
  • C #define文のリストを変換する崇高のマルチカーソルとviのキーバインディングを使用している場合:)だけでいくつかのキーストロークである
関連する問題