【发布时间】:2023-03-15 05:10:02
【问题描述】:
我正在使用 elixir 并遵循来自 http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/ 博文。
我遇到了跟踪哪个模拟函数对应的问题 哪个测试。我为 api 包装器的测试环境添加了一个模拟模块。当我向 mock api 模块添加模拟函数时,我发现我不记得编写了哪些函数来返回哪些测试的结果。
我一直在尝试找出一种方法来使用宏在测试附近定义模拟方法。作为学习练习,我也对这个问题感兴趣。
以下是我设想的工作方式:
defmodule SomeMockModule do
end
defmodule MockUtil do
defmacro add_mock module, block do
# <THE MISSING PIECE>
end
end
defmodule Test do
use ExUnit.Case
require MockUtil
MockUtil.add_mock SomeMockModule do
def some_func do
"mock value"
end
end
test "The mock value is returned" do
assert SomeMockModule.some_func == "mock value"
end
end
这类似于关于开放模块的问题: Open modules in Elixir? 但是我想知道如何在编译时而不是运行时做到这一点。
我环顾四周,没有发现任何说它可以或不能在编译时完成。
在某种程度上,这是一个花哨的复制和粘贴:)
到目前为止我所尝试的:
1)以下工作,但似乎相当混乱。它需要更改模拟模块。我想弄清楚是否有办法在没有之前编译的情况下做到这一点。
defmodule MockUtil do
defmacro register_function( _module, do: block )do
Module.put_attribute Test, :func_attr, block
end
end
defmodule Test do
require MockUtil
Module.register_attribute __MODULE__,
:func_attr,
accumulate: true, persist: false
defmacro define_functions(_env) do
@func_attr
end
MockUtil.register_function SomeMockModule do
def foo_bar do
IO.puts "Inside foo_bar."
end
end
end
defmodule SomeMockModule do
@before_compile {Test, :define_functions}
end
SomeMockModule.foo_bar
2)我也试过,代替:
Module.eval_quoted module, block
但是它会引发错误:
could not call eval_quoted on module {:__aliases__, [counter: 0, line: 10], [:SomeMockModule]} because it was already compiled
我想我遇到了编译问题。
有没有办法在编译时向模块添加函数?
【问题讨论】:
标签: elixir