混合处理配置值
Handling configuration values in mix
我目前正在努力处理混合配置值(特别是在 运行 测试时)。这是我的场景:
- 我有一个客户端库,带有一些通用配置值(密钥、机密、区域)。
- 我想测试当没有设置区域值时会发生什么
- 我在
/config
中没有 test.exs
文件
我目前是这样做的(但这行不通)。
正在测试的模块(简化):
defmodule Streamex.Client do
@api_region Application.get_env(:streamex, :region)
@api_key Application.get_env(:streamex, :key)
@api_secret Application.get_env(:streamex, :secret)
@api_version "v1.0"
@api_url "api.getstream.io/api"
def full_url(%Request{} = r) do
url = <<"?api_key=", @api_key :: binary>>
end
end
测试:
setup_all do
Streamex.start
Application.put_env :streamex, :key, "KEY"
Application.put_env :streamex, :secret, "SECRET"
Application.put_env :streamex, :secret, ""
end
当 运行 mix test
时发生的情况是,根据这些值设置属性的主模块由于找不到有效值而抛出以下错误:
lib/streamex/client.ex:36: invalid literal nil in <<>>
我还在开始,所以这看起来很明显,但我在阅读文档后找不到解决方案。
问题是您将 Application.get_env
的 return 值存储在模块属性中,该属性在 compile 时计算。如果您更改测试中的值,它不会反映在模块属性中——您将始终获得 mix
编译该模块时存在的值,其中包括评估 config/config.exs
和所有mix
在编译该模块之前编译的模块。解决方法是将可以更改的变量移动到函数中,并在使用时调用这些函数:
defmodule Streamex.Client do
@api_version "v1.0"
@api_url "api.getstream.io/api"
def full_url(%Request{} = r) do
url = <<"?api_key=", api_key :: binary>>
end
def api_region, do: Application.get_env(:streamex, :region)
def api_key, do: Application.get_env(:streamex, :key)
def api_secret, do: Application.get_env(:streamex, :secret)
end
请注意,如果这是一个库,并且您希望库的用户能够在其配置文件中配置值,您必须在运行时使用函数调用因为应用程序的依赖项是在应用程序之前编译的。
我目前正在努力处理混合配置值(特别是在 运行 测试时)。这是我的场景:
- 我有一个客户端库,带有一些通用配置值(密钥、机密、区域)。
- 我想测试当没有设置区域值时会发生什么
- 我在
/config
中没有
test.exs
文件
我目前是这样做的(但这行不通)。 正在测试的模块(简化):
defmodule Streamex.Client do
@api_region Application.get_env(:streamex, :region)
@api_key Application.get_env(:streamex, :key)
@api_secret Application.get_env(:streamex, :secret)
@api_version "v1.0"
@api_url "api.getstream.io/api"
def full_url(%Request{} = r) do
url = <<"?api_key=", @api_key :: binary>>
end
end
测试:
setup_all do
Streamex.start
Application.put_env :streamex, :key, "KEY"
Application.put_env :streamex, :secret, "SECRET"
Application.put_env :streamex, :secret, ""
end
当 运行 mix test
时发生的情况是,根据这些值设置属性的主模块由于找不到有效值而抛出以下错误:
lib/streamex/client.ex:36: invalid literal nil in <<>>
我还在开始,所以这看起来很明显,但我在阅读文档后找不到解决方案。
问题是您将 Application.get_env
的 return 值存储在模块属性中,该属性在 compile 时计算。如果您更改测试中的值,它不会反映在模块属性中——您将始终获得 mix
编译该模块时存在的值,其中包括评估 config/config.exs
和所有mix
在编译该模块之前编译的模块。解决方法是将可以更改的变量移动到函数中,并在使用时调用这些函数:
defmodule Streamex.Client do
@api_version "v1.0"
@api_url "api.getstream.io/api"
def full_url(%Request{} = r) do
url = <<"?api_key=", api_key :: binary>>
end
def api_region, do: Application.get_env(:streamex, :region)
def api_key, do: Application.get_env(:streamex, :key)
def api_secret, do: Application.get_env(:streamex, :secret)
end
请注意,如果这是一个库,并且您希望库的用户能够在其配置文件中配置值,您必须在运行时使用函数调用因为应用程序的依赖项是在应用程序之前编译的。