i struggling handle config values in mix (particularly when running tests). scenario:
- i have client library, common config values (key, secret, region).
- i want test happens when there's no region value setup
- i have no
test.exs
file in/config
i'm doing (and doesn't work). module being tested (simplified):
defmodule streamex.client @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) url = <<"?api_key=", @api_key :: binary>> end end
test:
setup_all streamex.start application.put_env :streamex, :key, "key" application.put_env :streamex, :secret, "secret" application.put_env :streamex, :secret, "" end
what happens when running mix test
main module, sets attributes values, throws following error since can't find valid values:
lib/streamex/client.ex:36: invalid literal nil in <<>>
i'm still starting may seem obvious, can't find solution after reading docs.
the problem you're storing return value of application.get_env
in module attribute, evaluated @ compile time. if change values in tests, won't reflected in module attribute -- you'll value that's present when mix
compiled module, includes evaluating config/config.exs
, modules mix
compiled before compiling module. fix move variables can changed function , call functions whenever they're used:
defmodule streamex.client @api_version "v1.0" @api_url "api.getstream.io/api" def full_url(%request{} = r) 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
note if library , want users of library able configure values in config files, have use function calls @ runtime dependencies of app compiled before app.
Comments
Post a Comment