Elixir Mocking:将模块分配给模块属性

时间:2018-01-11 08:53:47

标签: elixir

对于测试,我想做一个模拟,如JoséValimhere

所述

但我一直收到“CaseClauseError”错误。如果有兴趣,我做了一个简单的项目here

使用Application.get_env将模块绑定到模块属性时,例如

defmodule Att do
  @file Application.get_env(:att, :file_module)

  def hello do
    file = Application.get_env(:att, :file_module)
    file.hello()
    # @file.hello
  end
end

导致以下编译错误:

mix compile
    == Compilation error in file lib/att.ex ==
** (CaseClauseError) no case clause matching: [{:file, Att.Real, false, 2}]
    lib/att.ex:5: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6

如果我注释掉@file Application.get_env(:att, :file_module)没有问题,并且在hello函数中使用file = Application.get_env(:att,:file_module)就可以了。

问题不是Application.get_env特定的,就像执行以下操作一样

defmodule Att do
  # @file Application.get_env(:att, :file_module)
  @file_mock Att.Mock

  def hello do
    file = Application.get_env(:att, :file_module)
    file.hello()
    Att.Mock.hello()
    # @file.hello
  end
end

然后@file_mock Att.Mock导致相同的CaseClauseError。问题似乎是将模块分配给模块属性。

1 个答案:

答案 0 :(得分:1)

@file是一个特殊的模块属性,用于存储要在stacktraces中使用的文件名。如果你改为将它分配给另一个名字,它应该可以正常工作。

  

<强> @file

     

更改函数或宏的stacktraces中使用的文件名   属于该属性,例如:

defmodule MyModule do
  @doc "Hello world"
  @file "hello.ex"
  def hello do
    "world"
  end
end

Source